Re: [PATCH v2 2/2] staging: rtl8188eu: Better memory clean-up in efuse_phymap_to_logical()
> diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c > b/drivers/staging/rtl8188eu/core/rtw_efuse.c > index 697876b..359f169 100644 > --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c > +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c [...] > -exit: > +cleanup2: > + kfree(eFuseWord); > + > +cleanup1: > kfree(efuseTbl); > > - kfree(eFuseWord); > +exit: > + ; > } You are not using the most recent version of the code. The issue has already been fixed. Concretely, this part of the function now reads: exit: kfree(eFuseWord); eFuseWord_failed: kfree(efuseTbl); julia ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/2] staging: rtl8188eu: Deletion of unnecessary checks before three function calls
On Wed, 12 Nov 2014, SF Markus Elfring wrote: > From: Markus Elfring > Date: Wed, 12 Nov 2014 20:25:49 +0100 > > The functions kfree(), rtw_free_netdev() and vfree() test whether their > argument is NULL and then return immediately. Thus the test around the call > is not needed. > > This issue was detected by using the Coccinelle software. > > Signed-off-by: Markus Elfring > --- > drivers/staging/rtl8188eu/core/rtw_efuse.c | 3 +-- > drivers/staging/rtl8188eu/core/rtw_mlme.c| 3 +-- > drivers/staging/rtl8188eu/core/rtw_sta_mgt.c | 3 +-- > drivers/staging/rtl8188eu/core/rtw_xmit.c| 6 ++ > drivers/staging/rtl8188eu/os_dep/usb_intf.c | 6 +++--- > 5 files changed, 8 insertions(+), 13 deletions(-) > > diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c > b/drivers/staging/rtl8188eu/core/rtw_efuse.c > index 5b997b2..697876b 100644 > --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c > +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c > @@ -212,8 +212,7 @@ efuse_phymap_to_logical(u8 *phymap, u16 _offset, u16 > _size_byte, u8 *pbuf) > exit: > kfree(efuseTbl); > > - if (eFuseWord) > - kfree(eFuseWord); > + kfree(eFuseWord); > } As far as I can tell, the 2/2 patch in this series proposes a completely different fix for this code. When you send a series, patch n+1/m is supposed to apply to the result of patch n/m. In any case, you can let this one go, because the problem has been fixed already. julia ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 2/2] staging: rtl8188eu: Better memory clean-up in efuse_phymap_to_logical()
+ goto cleanup1; >>> >>> 1) Don't use GW-BASIC label names. Label names should reflect what the >>> label does such as free_fuse_word or free_fuse_tabel. >>> >>> 2) Don't use do-nothing labels. Just return directly. >> >> Does the document "CodingStyle" need any extensions for special cases? > > I don't understand. Should the naming convention become more explicit for jump labels? > CodingStyle says: > > "If there is no cleanup needed then just return directly." Do you want that I send another update suggestion with other corrections for jump labels in the affected function implementation? Regards, Markus ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 2/2] staging: rtl8188eu: Better memory clean-up in efuse_phymap_to_logical()
> You are not using the most recent version of the code. The issue has > already been fixed. Thanks for your reminder. https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/drivers/staging/rtl8188eu/core/rtw_efuse.c?id=3cfab18ce55282a85e2c7e5db15c5daf065efdb4 Regards, Markus ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 1/4] staging: comedi: das6402: add basic (*do_cmdtest) for AI async commands
On 12/11/14 23:00, H Hartley Sweeten wrote: Currently the async command support in this driver consists of just the stubbed in functions. Flesh out the (*do_cmdtest) function for basic support of timed analog input acquisitions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das6402.c | 105 ++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index f3909f3..511b6b3 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -35,6 +35,7 @@ #include #include "../comedidev.h" +#include "comedi_fc.h" #include "8253.h" /* @@ -207,11 +208,113 @@ static int das6402_ai_cmd(struct comedi_device *dev, return -EINVAL; } +static int das6402_ai_check_chanlist(struct comedi_device *dev, +struct comedi_subdevice *s, +struct comedi_cmd *cmd) +{ + unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); + unsigned int range0 = CR_RANGE(cmd->chanlist[0]); + unsigned int aref0 = CR_AREF(cmd->chanlist[0]); + int i; + + for (i = 1; i < cmd->chanlist_len; i++) { + unsigned int chan = CR_CHAN(cmd->chanlist[i]); + unsigned int range = CR_RANGE(cmd->chanlist[i]); + unsigned int aref = CR_AREF(cmd->chanlist[i]); + + if (chan != chan0 + i) { + dev_dbg(dev->class_dev, + "chanlist must be consecutive\n"); + return -EINVAL; + } + + if (range != range0) { + dev_dbg(dev->class_dev, + "chanlist must have the same range\n"); + return -EINVAL; + } + + if (aref != aref0) { + dev_dbg(dev->class_dev, + "chanlist must have the reference\n"); Shouldn't that say the _same_ reference? -- -=( Ian Abbott @ MEV Ltd.E-mail: )=- -=( Web: http://www.mev.co.uk/ )=- ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 0/4] staging: comedi: das6402: add basic AI async command support
On 12/11/14 23:00, H Hartley Sweeten wrote: This driver was _really_ broken and had to be rewritten. During that rewrite the async command support was stubbed in but not completed. This series adds support for basic AI async commands. H Hartley Sweeten (4): staging: comedi: das6402: add basic (*do_cmdtest) for AI async commands staging: comedi: das6402: introduce das6402_ai_set_mode() staging: comedi: das6402: read analog input samples in interrupt handler staging: comedi: das6402: add (*do_cmd) for AI async commands drivers/staging/comedi/drivers/das6402.c | 198 +++ 1 file changed, 178 insertions(+), 20 deletions(-) Just a minor niggle in one of the debug messages in patch 1. Reviewed-by: Ian Abbott -- -=( Ian Abbott @ MEV Ltd.E-mail: )=- -=( Web: http://www.mev.co.uk/ )=- ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 12/30] staging: comedi: dmm32at: use 8255 module for Digital I/O subdevice
On 12/11/14 16:46, Hartley Sweeten wrote: OK, so no change needed. Side-note... Currently the board reset also probes the board to try and "verify" that the board is actually a dmm32at. Do you think this is actually necessary? Not strictly necessary, but may help if the user configures it incorrectly. I feel the board reset just needs to set the RESETA bit to reset the board. This causes a full reset of all features of the board, including the DACs, the FIFO, the digital I/O, and all internal registers. The other writes to the board registers are not needed since they are only setup the registers for the verify check. The udelay() calls can also probably be removed since there is no mention of a delay needed after the reset in the user manual. Without knowing for sure (it might be something needed that was neglected from the user manual), I'd leave it in or change it to use usleep_range(), e.g. usleep_range(1000, 1). There is still the issue of the SD1/0 bits in the AI status register. These provide feedback of how the jumpers are set to configure the AI channels for single-ended or differential input. This could be worked out so the differential mode actually works. The all single-ended and all-differential cases should be straightforward. The "half and half" (or rather "third and two-thirds") cases would be tricky as you may end up with a gap in the channel numbers, and the support for subdevices with channel-specific flags (SDF_FLAGS) is currently disabled in the comedi core. -- -=( Ian Abbott @ MEV Ltd.E-mail: )=- -=( Web: http://www.mev.co.uk/ )=- ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v9 0/9] dw-hdmi: convert imx hdmi to bridge/dw_hdmi
We found Freescale imx6 and Rockchip rk3288 and Ingenic JZ4780 (Xburst/MIPS) use the interface compatible Designware HDMI IP, but they also have some lightly differences, such as phy pll configuration, register width(imx hdmi register is one byte, but rk3288 is 4 bytes width and can only be accessed by word), 4K support(imx6 doesn't support 4k, but rk3288 does), and HDMI2.0 support. To reuse the imx-hdmi driver, we make this patch set: (1): fix some CodingStyle warning to make checkpatch happy (2): split out imx-soc code from imx-hdmi to dw_hdmi-imx.c (3): move imx-hdmi to bridge/dw-hdmi, and convert it to a drm_bridge driver (4): add rockchip rk3288 platform specific code dw_hdmi-rockchip.c Changes in v9: - move some phy configuration to platform driver Changes in v8: - correct some spelling mistake - modify ddc-i2c-bus and interrupt description - Add documentation for rockchip dw hdmi - add support for rockchip rk3288 hdmi Changes in v7: - remove unused variables from structure dw_hdmi - remove a wrong modification - add copyrights for dw_hdmi-imx.c Changes in v6: - rearrange the patch order - move some modification to patch#6 - refactor register access without reg_shift - move some modification from patch#5 Changes in v5: - refactor reg-io-width Changes in v4: - fix checkpatch CHECK - defer probe ddc i2c adapter Changes in v3: - split multi register access to one indepent patch Changes in v2: - use git format -M to generate these patch Andy Yan (8): staging: imx-drm: imx-hdmi: make checkpatch happy staging: imx-drm: imx-hdmi: return defer if can't get ddc i2c adapter staging: imx-drm: imx-hdmi: split imx soc specific code from imx-hdmi staging: imx-drm: imx-hdmi: move imx-hdmi to bridge/dw_hdmi dt-bindings: add document for dw_hdmi drm: bridge/dw_hdmi: add support for multi byte register width access dt-bindings: Add documentation for rockchip dw hdmi drm: bridge/dw_hdmi: add rockchip rk3288 support Yakir Yang (1): drm: bridge/dw_hdmi: convert dw-hdmi to drm_bridge mode .../devicetree/bindings/drm/bridge/dw_hdmi.txt | 40 ++ .../devicetree/bindings/video/dw_hdmi-rockchip.txt | 43 ++ drivers/gpu/drm/bridge/Kconfig | 5 + drivers/gpu/drm/bridge/Makefile| 1 + .../imx-hdmi.c => gpu/drm/bridge/dw_hdmi.c}| 762 + .../imx-hdmi.h => gpu/drm/bridge/dw_hdmi.h}| 8 +- drivers/gpu/drm/rockchip/Kconfig | 10 + drivers/gpu/drm/rockchip/Makefile | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 328 + drivers/staging/imx-drm/Kconfig| 1 + drivers/staging/imx-drm/Makefile | 2 +- drivers/staging/imx-drm/dw_hdmi-imx.c | 274 include/drm/bridge/dw_hdmi.h | 60 ++ 13 files changed, insertions(+), 425 deletions(-) create mode 100644 Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt create mode 100644 Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt rename drivers/{staging/imx-drm/imx-hdmi.c => gpu/drm/bridge/dw_hdmi.c} (70%) rename drivers/{staging/imx-drm/imx-hdmi.h => gpu/drm/bridge/dw_hdmi.h} (99%) create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c create mode 100644 drivers/staging/imx-drm/dw_hdmi-imx.c create mode 100644 include/drm/bridge/dw_hdmi.h -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v9 1/9] staging: imx-drm: imx-hdmi: make checkpatch happy
CHECK: Alignment should match open parenthesis + if ((hdmi->vic == 10) || (hdmi->vic == 11) || + (hdmi->vic == 12) || (hdmi->vic == 13) || CHECK: braces {} should be used on all arms of this statement + if (hdmi->hdmi_data.video_mode.mdvi) [...] + else { [...] Signed-off-by: Andy Yan --- Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: - rearrange the patch order Changes in v5: None Changes in v4: - fix checkpatch CHECK Changes in v3: None Changes in v2: None drivers/staging/imx-drm/imx-hdmi.c | 97 +++--- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index aaec6b2..79daec4 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -163,7 +163,7 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) } static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, - u8 shift, u8 mask) +u8 shift, u8 mask) { hdmi_modb(hdmi, data << shift, mask, reg); } @@ -327,7 +327,7 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, } static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi, - unsigned long pixel_clk) +unsigned long pixel_clk) { unsigned int clk_n, clk_cts; @@ -338,7 +338,7 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi, if (!clk_cts) { dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", -__func__, pixel_clk); + __func__, pixel_clk); return; } @@ -477,13 +477,11 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) u16 coeff_b = (*csc_coeff)[1][i]; u16 coeff_c = (*csc_coeff)[2][i]; - hdmi_writeb(hdmi, coeff_a & 0xff, - HDMI_CSC_COEF_A1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2); hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); - hdmi_writeb(hdmi, coeff_c & 0xff, - HDMI_CSC_COEF_C1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2); hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); } @@ -535,21 +533,22 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; u8 val, vp_conf; - if (hdmi_data->enc_out_format == RGB - || hdmi_data->enc_out_format == YCBCR444) { - if (!hdmi_data->enc_color_depth) + if (hdmi_data->enc_out_format == RGB || + hdmi_data->enc_out_format == YCBCR444) { + if (!hdmi_data->enc_color_depth) { output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; - else if (hdmi_data->enc_color_depth == 8) { + } else if (hdmi_data->enc_color_depth == 8) { color_depth = 4; output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; - } else if (hdmi_data->enc_color_depth == 10) + } else if (hdmi_data->enc_color_depth == 10) { color_depth = 5; - else if (hdmi_data->enc_color_depth == 12) + } else if (hdmi_data->enc_color_depth == 12) { color_depth = 6; - else if (hdmi_data->enc_color_depth == 16) + } else if (hdmi_data->enc_color_depth == 16) { color_depth = 7; - else + } else { return; + } } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { if (!hdmi_data->enc_color_depth || hdmi_data->enc_color_depth == 8) @@ -561,8 +560,9 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) else return; output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; - } else + } else { return; + } /* set the packetizer registers */ val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & @@ -623,34 +623,34 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) } static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi, - unsigned char bit) + unsigned char bit) { hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET, HDMI_PHY_TST0_TSTCLR_MASK, HDMI_
[PATCH v9 2/9] staging: imx-drm: imx-hdmi: return defer if can't get ddc i2c adapter
drm driver may probe before the i2c bus, so the driver should defer probing until it is available Signed-off-by: Andy Yan --- Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: - defer probe ddc i2c adapter Changes in v3: None Changes in v2: None drivers/staging/imx-drm/imx-hdmi.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 79daec4..c2b035a 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1611,8 +1611,11 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); - if (!hdmi->ddc) + if (!hdmi->ddc) { dev_dbg(hdmi->dev, "failed to read ddc node\n"); + of_node_put(ddc_node); + return -EPROBE_DEFER; + } of_node_put(ddc_node); } else { -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v9 5/9] dt-bindings: add document for dw_hdmi
Signed-off-by: Andy Yan --- Changes in v9: None Changes in v8: - correct some spelling mistake - modify ddc-i2c-bus and interrupt description Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None .../devicetree/bindings/drm/bridge/dw_hdmi.txt | 40 ++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt new file mode 100644 index 000..0558442 --- /dev/null +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt @@ -0,0 +1,40 @@ +DesignWare HDMI bridge bindings + +Required properities: +- compatible: platform specific such as: + * "fsl,imx6q-hdmi" + * "fsl,imx6dl-hdmi" + * "rockchip,rk3288-dw-hdmi" +- reg: physical base address of the controller and length +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing +- interrupts: The HDMI interrupt number + +Optional properties +- reg-io-width: the width of the reg:1,4, default set to 1 if not present + +Example: + hdmi: hdmi@012 { + compatible = "fsl,imx6q-hdmi"; + reg = <0x0012 0x9000>; + interrupts = <0 115 0x04>; + gpr = <&gpr>; + clocks = <&clks 123>, <&clks 124>; + clock-names = "iahb", "isfr"; + ddc-i2c-bus = <&i2c2>; + + port@0 { + reg = <0>; + + hdmi_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_hdmi>; + }; + }; + + port@1 { + reg = <1>; + + hdmi_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_hdmi>; + }; + }; + }; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v9 4/9] staging: imx-drm: imx-hdmi: move imx-hdmi to bridge/dw_hdmi
the original imx hdmi driver is under staging/imx-drm, which depends on imx-drm, so move the imx hdmi driver out to drm/bridge and rename imx-hdmi to dw_hdmi Signed-off-by: Andy Yan --- Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: - use git format -M to generate these patch drivers/gpu/drm/bridge/Kconfig | 5 + drivers/gpu/drm/bridge/Makefile| 1 + .../imx-hdmi.c => gpu/drm/bridge/dw_hdmi.c}| 281 +++-- .../imx-hdmi.h => gpu/drm/bridge/dw_hdmi.h}| 46 +--- drivers/staging/imx-drm/Kconfig| 1 + drivers/staging/imx-drm/Makefile | 2 +- drivers/staging/imx-drm/dw_hdmi-imx.c | 70 ++--- include/drm/bridge/dw_hdmi.h | 57 + 8 files changed, 243 insertions(+), 220 deletions(-) rename drivers/{staging/imx-drm/imx-hdmi.c => gpu/drm/bridge/dw_hdmi.c} (83%) rename drivers/{staging/imx-drm/imx-hdmi.h => gpu/drm/bridge/dw_hdmi.h} (97%) create mode 100644 include/drm/bridge/dw_hdmi.h diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 884923f..26162ef 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -3,3 +3,8 @@ config DRM_PTN3460 depends on DRM select DRM_KMS_HELPER ---help--- + +config DRM_DW_HDMI + bool "Synopsys DesignWare High-Definition Multimedia Interface" + depends on DRM + select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index b4733e1..d8a8cfd 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,3 +1,4 @@ ccflags-y := -Iinclude/drm obj-$(CONFIG_DRM_PTN3460) += ptn3460.o +obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c similarity index 83% rename from drivers/staging/imx-drm/imx-hdmi.c rename to drivers/gpu/drm/bridge/dw_hdmi.c index c7e5f12..e9f0dfe 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -6,8 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * SH-Mobile High-Definition Multimedia Interface (HDMI) driver - * for SLISHDMI13T and SLIPHDMIT IP cores + * Designware High-Definition Multimedia Interface (HDMI) driver * * Copyright (C) 2010, Guennadi Liakhovetski */ @@ -24,8 +23,9 @@ #include #include #include +#include -#include "imx-hdmi.h" +#include "dw_hdmi.h" #define HDMI_EDID_LEN 512 @@ -101,15 +101,15 @@ struct hdmi_data_info { struct hdmi_vmode video_mode; }; -struct imx_hdmi { +struct dw_hdmi { struct drm_connector connector; struct drm_encoder encoder; - enum imx_hdmi_devtype dev_type; + enum dw_hdmi_devtype dev_type; struct device *dev; struct hdmi_data_info hdmi_data; - const struct imx_hdmi_plat_data *plat_data; + const struct dw_hdmi_plat_data *plat_data; void *priv; int vic; @@ -127,17 +127,17 @@ struct imx_hdmi { int ratio; }; -static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset) +static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) { writeb(val, hdmi->regs + offset); } -static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset) +static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) { return readb(hdmi->regs + offset); } -static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) +static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) { u8 val = hdmi_readb(hdmi, reg) & ~mask; @@ -145,13 +145,13 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) hdmi_writeb(hdmi, val, reg); } -static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, +static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg, u8 shift, u8 mask) { hdmi_modb(hdmi, data << shift, mask, reg); } -static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, +static void hdmi_set_clock_regenerator_n(struct dw_hdmi *hdmi, unsigned int value) { hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1); @@ -162,7 +162,7 @@ static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); } -static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts) +static void hdmi_regenerate_cts(struct dw_hdmi *hdmi, unsigned int cts) { /* Must be set/cleared first */ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); @@ -309,7 +309,7 @@ static unsigned int hdmi_compute_
[PATCH v9 3/9] staging: imx-drm: imx-hdmi: split imx soc specific code from imx-hdmi
IMX6 and Rockchip RK3288 and JZ4780 (Ingenic Xburst/MIPS) use the interface compatible Designware HDMI IP, but they also have some lightly differences, such as phy pll configuration, register width, 4K support, clk useage, and the crtc mux configuration is also platform specific. To reuse the imx hdmi driver, split the platform specific code out to dw_hdmi-imx.c. Signed-off-by: Andy Yan --- Changes in v9: None Changes in v8: None Changes in v7: - remove unused variables from structure dw_hdmi - remove a wrong modification - add copyrights for dw_hdmi-imx.c Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/staging/imx-drm/Makefile | 2 +- drivers/staging/imx-drm/dw_hdmi-imx.c | 217 + drivers/staging/imx-drm/imx-hdmi.c| 255 -- drivers/staging/imx-drm/imx-hdmi.h| 43 ++ 4 files changed, 322 insertions(+), 195 deletions(-) create mode 100644 drivers/staging/imx-drm/dw_hdmi-imx.c diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index 582c438..809027d 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o obj-$(CONFIG_DRM_IMX_IPUV3)+= imx-ipuv3-crtc.o -obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o +obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o dw_hdmi-imx.o diff --git a/drivers/staging/imx-drm/dw_hdmi-imx.c b/drivers/staging/imx-drm/dw_hdmi-imx.c new file mode 100644 index 000..0db978e --- /dev/null +++ b/drivers/staging/imx-drm/dw_hdmi-imx.c @@ -0,0 +1,217 @@ +/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. + * + * derived from imx-hdmi.c(renamed to bridge/dw_hdmi.c now) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "imx-drm.h" +#include "imx-hdmi.h" + +struct imx_hdmi_priv { + struct device *dev; + struct clk *isfr_clk; + struct clk *iahb_clk; + struct regmap *regmap; +}; + +static const struct mpll_config imx_mpll_cfg[] = { + { + 4525, { + { 0x01e0, 0x }, + { 0x21e1, 0x }, + { 0x41e2, 0x } + }, + }, { + 9250, { + { 0x0140, 0x0005 }, + { 0x2141, 0x0005 }, + { 0x4142, 0x0005 }, + }, + }, { + 14850, { + { 0x00a0, 0x000a }, + { 0x20a1, 0x000a }, + { 0x40a2, 0x000a }, + }, + }, { + ~0UL, { + { 0x00a0, 0x000a }, + { 0x2001, 0x000f }, + { 0x4002, 0x000f }, + }, + } +}; + +static const struct curr_ctrl imx_cur_ctr[] = { + /* pixelclk bpp8bpp10 bpp12 */ + { + 5400, { 0x091c, 0x091c, 0x06dc }, + }, { + 5840, { 0x091c, 0x06dc, 0x06dc }, + }, { + 7200, { 0x06dc, 0x06dc, 0x091c }, + }, { + 7425, { 0x06dc, 0x0b5c, 0x091c }, + }, { + 11880, { 0x091c, 0x091c, 0x06dc }, + }, { + 21600, { 0x06dc, 0x0b5c, 0x091c }, + } +}; + +static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi) +{ + struct device_node *np = hdmi->dev->of_node; + + hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); + if (IS_ERR(hdmi->regmap)) { + dev_err(hdmi->dev, "Unable to get gpr\n"); + return PTR_ERR(hdmi->regmap); + } + + hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); + if (IS_ERR(hdmi->isfr_clk)) { + dev_err(hdmi->dev, "Unable to get HDMI isfr clk\n"); + return PTR_ERR(hdmi->isfr_clk); + } + + hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); + if (IS_ERR(hdmi->iahb_clk)) { + dev_err(hdmi->dev, "Unable to get HDMI iahb clk\n"); + return PTR_ERR(hdmi->iahb_clk); + } + + return 0; +} + +static void *imx_hdmi_imx_setup(struct platform_device *pdev) +{ + struct imx_hdmi_priv *hdmi; + int ret; + + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return ERR_PTR(-ENOMEM); + hdmi->dev = &pdev->dev; + + ret = imx_hdmi_parse_dt(hdmi); + if (ret < 0) + return ERR_PTR(ret); + ret = clk_prepare_enable(hdmi->isfr_clk); + if (ret) { + dev_err(hdmi->dev, + "Cannot enable HDMI isfr clock: %d\n", ret); +
[PATCH v9 6/9] drm: bridge/dw_hdmi: add support for multi byte register width access
On rockchip rk3288, only word(32-bit) accesses are permitted for hdmi registers. Byte width accesses (writeb, readb) generate an imprecise external abort. Signed-off-by: Andy Yan --- Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: - move some modification to patch#6 - refactor register access without reg_shift Changes in v5: - refactor reg-io-width Changes in v4: None Changes in v3: - split multi register access to one indepent patch Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c | 57 +++- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index e9f0dfe..978c709 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -101,6 +101,11 @@ struct hdmi_data_info { struct hdmi_vmode video_mode; }; +union dw_reg_ptr { + u32 __iomem *p32; + u8 __iomem *p8; +}; + struct dw_hdmi { struct drm_connector connector; struct drm_encoder encoder; @@ -121,20 +126,43 @@ struct dw_hdmi { struct regmap *regmap; struct i2c_adapter *ddc; - void __iomem *regs; + union dw_reg_ptr regs; unsigned int sample_rate; int ratio; + + void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read)(struct dw_hdmi *hdmi, int offset); }; +static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset) +{ + writel(val, hdmi->regs.p32 + offset); +} + +static u8 dw_hdmi_readl(struct dw_hdmi *hdmi, int offset) +{ + return readl(hdmi->regs.p32 + offset); +} + +static void dw_hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) +{ + writeb(val, hdmi->regs.p8 + offset); +} + +static u8 dw_hdmi_readb(struct dw_hdmi *hdmi, int offset) +{ + return readb(hdmi->regs.p8 + offset); +} + static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) { - writeb(val, hdmi->regs + offset); + hdmi->write(hdmi, val, offset); } static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) { - return readb(hdmi->regs + offset); + return hdmi->read(hdmi, offset); } static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) @@ -1499,6 +1527,23 @@ static int dw_hdmi_bind(struct device *dev, struct device *master, void *data) struct device_node *ddc_node; struct resource *iores; int ret, irq; + u32 val = 1; + + of_property_read_u32(np, "reg-io-width", &val); + + switch (val) { + case 4: + hdmi->write = dw_hdmi_writel; + hdmi->read = dw_hdmi_readl; + break; + case 1: + hdmi->write = dw_hdmi_writeb; + hdmi->read = dw_hdmi_readb; + break; + default: + dev_err(dev, "reg-io-width must be 1 or 4\n"); + return -EINVAL; + } ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { @@ -1525,9 +1570,9 @@ static int dw_hdmi_bind(struct device *dev, struct device *master, void *data) return ret; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->regs = devm_ioremap_resource(dev, iores); - if (IS_ERR(hdmi->regs)) - return PTR_ERR(hdmi->regs); + hdmi->regs.p32 = devm_ioremap_resource(dev, iores); + if (IS_ERR(hdmi->regs.p32)) + return PTR_ERR(hdmi->regs.p32); if (hdmi->plat_data->setup) hdmi->priv = hdmi->plat_data->setup(pdev); -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v9 7/9] drm: bridge/dw_hdmi: convert dw-hdmi to drm_bridge mode
From: Yakir Yang keep the connector & birdge in dw_hdmi.c, handle encoder in dw_hdmi-imx.c, as most of the encoder operation are platform specific such as crtc select and panel format set Signed-off-by: Andy Yan Signed-off-by: Yakir Yang --- Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: - move some modification from patch#5 Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c | 228 +++--- drivers/staging/imx-drm/dw_hdmi-imx.c | 145 ++--- include/drm/bridge/dw_hdmi.h | 13 +- 3 files changed, 199 insertions(+), 187 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index 978c709..ed75147 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -11,7 +11,6 @@ * Copyright (C) 2010, Guennadi Liakhovetski */ -#include #include #include #include @@ -108,7 +107,8 @@ union dw_reg_ptr { struct dw_hdmi { struct drm_connector connector; - struct drm_encoder encoder; + struct drm_encoder *encoder; + struct drm_bridge *bridge; enum dw_hdmi_devtype dev_type; struct device *dev; @@ -1319,6 +1319,50 @@ static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) dw_hdmi_phy_disable(hdmi); } +static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + dw_hdmi_setup(hdmi, mode); + + /* Store the display mode for plugin/DKMS poweron events */ + memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); +} + +static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + dw_hdmi_poweroff(hdmi); +} + +static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + dw_hdmi_poweron(hdmi); +} + +static void dw_hdmi_bridge_destroy(struct drm_bridge *bridge) +{ + drm_bridge_cleanup(bridge); + kfree(bridge); +} + +static void dw_hdmi_bridge_nope(struct drm_bridge *bridge) +{ + /* do nothing */ +} + static enum drm_connector_status dw_hdmi_connector_detect(struct drm_connector *connector, bool force) { @@ -1360,60 +1404,7 @@ static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector); - return &hdmi->encoder; -} - -static void dw_hdmi_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct dw_hdmi *hdmi = container_of(encoder, struct dw_hdmi, encoder); - - dw_hdmi_setup(hdmi, mode); - - /* Store the display mode for plugin/DKMS poweron events */ - memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); -} - -static bool dw_hdmi_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static void dw_hdmi_encoder_disable(struct drm_encoder *encoder) -{ -} - -static void dw_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct dw_hdmi *hdmi = container_of(encoder, struct dw_hdmi, encoder); - - if (mode) - dw_hdmi_poweroff(hdmi); - else - dw_hdmi_poweron(hdmi); -} - -static void dw_hdmi_encoder_prepare(struct drm_encoder *encoder) -{ - struct dw_hdmi *hdmi = container_of(encoder, struct dw_hdmi, encoder); - - dw_hdmi_poweroff(hdmi); - - if (hdmi->plat_data->encoder_prepare) - hdmi->plat_data->encoder_prepare(&hdmi->connector, encoder); -} - -static void dw_hdmi_encoder_commit(struct drm_encoder *encoder) -{ - struct dw_hdmi *hdmi = container_of(encoder, struct dw_hdmi, encoder); - - if (hdmi->plat_data->encoder_commit) - hdmi->plat_data->encoder_commit(hdmi->priv, encoder); - - dw_hdmi_poweron(hdmi); + return hdmi->encoder; } void dw_hdmi_connector_destroy(struct drm_connector *connector) @@ -1422,19 +1413,6 @@ void dw_hdmi_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } -static struct drm_encoder_funcs dw_hdmi_encoder_funcs = { - .destr
[PATCH v9 8/9] dt-bindings: Add documentation for rockchip dw hdmi
Signed-off-by: Andy Yan --- Changes in v9: None Changes in v8: - Add documentation for rockchip dw hdmi Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None .../devicetree/bindings/video/dw_hdmi-rockchip.txt | 43 ++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt diff --git a/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt new file mode 100644 index 000..6ea6764 --- /dev/null +++ b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt @@ -0,0 +1,43 @@ +Rockchip specific extensions to the Synopsys Designware HDMI + + +Required properties: +- compatible: "rockchip,rk3288-dw-hdmi"; +- reg: physical base address of the controller and length +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing +- clocks: from common clock binding: handle to hdmi clock. +- clock-names: should be "clk" "hdcp_clk" +- rockchip,grf: this soc should set GRF regs to mux vopl/vopb. +- interrupts: HDMI interrupt number +- ports: contain a port node with endpoint definitions as defined in + Documentation/devicetree/bindings/media/video-interfaces.txt. For + vopb,set the reg = <0> and set the reg = <1> for vopl. +- reg-io-width: the width of the reg:1,4, the value should be 4 on + rk3288 platform + +Example: +hdmi: hdmi@ff98 { + compatible = "rockchip,rk3288-dw-hdmi"; + reg = <0xff98 0x2>; + reg-io-width = <4>; + ddc-i2c-bus = <&i2c5>; + rockchip,grf = <&grf>; + interrupts = ; + clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>; + clock-names = "clk", "hdcp_clk"; + status = "disabled"; + ports { + hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + hdmi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_hdmi>; + }; + hdmi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_hdmi>; + }; + }; + }; +}; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v9 9/9] drm: bridge/dw_hdmi: add rockchip rk3288 support
rk3288 hdmi is compatible with Designware hdmi this patch is depend on patch by Mark Yao Add drm driver for Rockchip Socs see https://lkml.org/lkml/2014/10/8/201 Signed-off-by: Andy Yan Signed-off-by: Yakir Yang --- Changes in v9: - move some phy configuration to platform driver Changes in v8: - add support for rockchip rk3288 hdmi Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c| 45 +++- drivers/gpu/drm/bridge/dw_hdmi.h| 3 +- drivers/gpu/drm/rockchip/Kconfig| 10 + drivers/gpu/drm/rockchip/Makefile | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 328 drivers/staging/imx-drm/dw_hdmi-imx.c | 8 + include/drm/bridge/dw_hdmi.h| 8 + 7 files changed, 399 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index ed75147..1dd1f0b 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -668,11 +668,15 @@ static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi, static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) { - while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { + u32 val; + + while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { if (msec-- == 0) return false; udelay(1000); } + hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0); + return true; } @@ -711,6 +715,13 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) HDMI_PHY_CONF0_ENTMDS_MASK); } +static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, +HDMI_PHY_CONF0_SPARECTRL_OFFSET, +HDMI_PHY_CONF0_SPARECTRL_MASK); +} + static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) { hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, @@ -746,6 +757,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, u8 val, msec; const struct mpll_config *mpll_cfg = hdmi->plat_data->mpll_cfg; const struct curr_ctrl *curr_ctr = hdmi->plat_data->cur_ctr; + const struct sym_term *sym_term = hdmi->plat_data->sym_term; if (prep) return -EINVAL; @@ -815,10 +827,17 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, hdmi_phy_i2c_write(hdmi, 0x, 0x13); /* PLLPHBYCTRL */ hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); + + for (i = 0; sym_term[i].mpixelclock != (~0UL); i++) + if (hdmi->hdmi_data.video_mode.mpixelclock <= + sym_term[i].mpixelclock) + break; + /* RESISTANCE TERM 133Ohm Cfg */ - hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */ + hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19); /* TXTERM */ /* PREEMP Cgf 0.00 */ - hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */ + hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09); /* CKSYMTXCTRL */ + /* TX/CK LVL 10 */ hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */ /* REMOVE CLK TERM */ @@ -834,6 +853,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, dw_hdmi_phy_gen2_txpwron(hdmi, 1); dw_hdmi_phy_gen2_pddq(hdmi, 0); + if (hdmi->dev_type == RK3288_HDMI) + dw_hdmi_phy_enable_spare(hdmi, 1); + /*Wait for PHY PLL lock */ msec = 5; do { @@ -1398,6 +1420,20 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) return 0; } +static enum drm_mode_status +dw_hdmi_connector_mode_valid(struct drm_connector *connector, +struct drm_display_mode *mode) +{ + struct dw_hdmi *hdmi = container_of(connector, + struct dw_hdmi, connector); + enum drm_mode_status mode_status = MODE_OK; + + if (hdmi->plat_data->mode_valid) + mode_status = hdmi->plat_data->mode_valid(connector, mode); + + return mode_status; +} + static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector *connector) { @@ -1422,6 +1458,7 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = { static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = { .get_modes = dw_hdmi_connector_get_modes, + .mode_valid = dw_hdmi_connector_mode_valid, .best_encoder = dw_hdmi_connector_best_encoder, }; @@ -1514,6 +1551,8 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_h
Re: [PATCH v9 9/9] drm: bridge/dw_hdmi: add rockchip rk3288 support
On 13/11/14 12:57, Andy Yan wrote: > rk3288 hdmi is compatible with Designware hdmi > > this patch is depend on patch by Mark Yao Add drm > driver for Rockchip Socs > > see https://lkml.org/lkml/2014/10/8/201 > > Signed-off-by: Andy Yan > Signed-off-by: Yakir Yang > > --- > > Changes in v9: > - move some phy configuration to platform driver > > Changes in v8: > - add support for rockchip rk3288 hdmi > > Changes in v7: None > Changes in v6: None > Changes in v5: None > Changes in v4: None > Changes in v3: None > Changes in v2: None > > drivers/gpu/drm/bridge/dw_hdmi.c| 45 +++- This patch looks like it does alot to the dw_hdmi.c as well and not just adds support for rk3288.. > drivers/gpu/drm/bridge/dw_hdmi.h| 3 +- > drivers/gpu/drm/rockchip/Kconfig| 10 + > drivers/gpu/drm/rockchip/Makefile | 2 +- > drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 328 > > drivers/staging/imx-drm/dw_hdmi-imx.c | 8 + > include/drm/bridge/dw_hdmi.h| 8 + > 7 files changed, 399 insertions(+), 5 deletions(-) > create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c > > diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c > b/drivers/gpu/drm/bridge/dw_hdmi.c > index ed75147..1dd1f0b 100644 > --- a/drivers/gpu/drm/bridge/dw_hdmi.c > +++ b/drivers/gpu/drm/bridge/dw_hdmi.c > @@ -668,11 +668,15 @@ static inline void hdmi_phy_test_dout(struct dw_hdmi > *hdmi, > > static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) > { > - while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { > + u32 val; > + > + while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { > if (msec-- == 0) > return false; > udelay(1000); > } > + hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0); > + > return true; > } > Is this a bug fix? > @@ -711,6 +715,13 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi > *hdmi, u8 enable) >HDMI_PHY_CONF0_ENTMDS_MASK); > } > > +static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable) > +{ > + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, > + HDMI_PHY_CONF0_SPARECTRL_OFFSET, > + HDMI_PHY_CONF0_SPARECTRL_MASK); > +} > + > static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) > { > hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, > @@ -746,6 +757,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, > unsigned char prep, > u8 val, msec; > const struct mpll_config *mpll_cfg = hdmi->plat_data->mpll_cfg; > const struct curr_ctrl *curr_ctr = hdmi->plat_data->cur_ctr; > + const struct sym_term *sym_term = hdmi->plat_data->sym_term; > > if (prep) > return -EINVAL; > @@ -815,10 +827,17 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, > unsigned char prep, > > hdmi_phy_i2c_write(hdmi, 0x, 0x13); /* PLLPHBYCTRL */ > hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); > + > + for (i = 0; sym_term[i].mpixelclock != (~0UL); i++) > + if (hdmi->hdmi_data.video_mode.mpixelclock <= > + sym_term[i].mpixelclock) > + break; > + > /* RESISTANCE TERM 133Ohm Cfg */ > - hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */ > + hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19); /* TXTERM */ > /* PREEMP Cgf 0.00 */ > - hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */ > + hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09); /* CKSYMTXCTRL */ > + All these seem generic improvements and not rk3288 specific? > /* TX/CK LVL 10 */ > hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */ > /* REMOVE CLK TERM */ > @@ -834,6 +853,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, > unsigned char prep, > dw_hdmi_phy_gen2_txpwron(hdmi, 1); > dw_hdmi_phy_gen2_pddq(hdmi, 0); > > + if (hdmi->dev_type == RK3288_HDMI) > + dw_hdmi_phy_enable_spare(hdmi, 1); > + > /*Wait for PHY PLL lock */ > msec = 5; > do { > @@ -1398,6 +1420,20 @@ static int dw_hdmi_connector_get_modes(struct > drm_connector *connector) > return 0; > } > > +static enum drm_mode_status > +dw_hdmi_connector_mode_valid(struct drm_connector *connector, > + struct drm_display_mode *mode) > +{ > + struct dw_hdmi *hdmi = container_of(connector, > + struct dw_hdmi, connector); > + enum drm_mode_status mode_status = MODE_OK; > + > + if (hdmi->plat_data->mode_valid) > + mode_status = hdmi->plat_data->mode_valid(connector, mode); > + > + return mode_status; > +} > + This too is disjoint from rk3288 support. > static struct drm_encoder *dw_hdmi_connector_best_encoder(struct > drm_connector >
Re: [PATCH v9 9/9] drm: bridge/dw_hdmi: add rockchip rk3288 support
Hi ZubairLK: thanks for your review. On 2014年11月13日 21:09, Zubair Lutfullah Kakakhel wrote: On 13/11/14 12:57, Andy Yan wrote: rk3288 hdmi is compatible with Designware hdmi this patch is depend on patch by Mark Yao Add drm driver for Rockchip Socs see https://lkml.org/lkml/2014/10/8/201 Signed-off-by: Andy Yan Signed-off-by: Yakir Yang --- Changes in v9: - move some phy configuration to platform driver Changes in v8: - add support for rockchip rk3288 hdmi Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c| 45 +++- This patch looks like it does alot to the dw_hdmi.c as well and not just adds support for rk3288.. drivers/gpu/drm/bridge/dw_hdmi.h| 3 +- drivers/gpu/drm/rockchip/Kconfig| 10 + drivers/gpu/drm/rockchip/Makefile | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 328 drivers/staging/imx-drm/dw_hdmi-imx.c | 8 + include/drm/bridge/dw_hdmi.h| 8 + 7 files changed, 399 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index ed75147..1dd1f0b 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -668,11 +668,15 @@ static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi, static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) { - while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { + u32 val; + + while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { if (msec-- == 0) return false; udelay(1000); } + hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0); + return true; } Is this a bug fix? It seems like a bug fix, I don't know why it works well on imx and jz4780 without this fix. HDMI_IN_I2CMPHY_STAT0 is a clear on write (1 to corresponding bit) status register to indicate i2c operation of the hdmi phy(i2c transfer done or err). After one register of the phy is configured by the i2cm, we should wait for the i2cmphydone bit set to 1, than configure the next register, than wait for the i2cmphydone bit set to 1But we should clear the indicate bit by write 1 to the corresponding bit after the the set to 1, otherwise the bit will hold on forever, this will give us a wrong signal in the next wait, and as a result , the phy register can't be configured as we want. @@ -711,6 +715,13 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) HDMI_PHY_CONF0_ENTMDS_MASK); } +static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, +HDMI_PHY_CONF0_SPARECTRL_OFFSET, +HDMI_PHY_CONF0_SPARECTRL_MASK); +} + static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) { hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, @@ -746,6 +757,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, u8 val, msec; const struct mpll_config *mpll_cfg = hdmi->plat_data->mpll_cfg; const struct curr_ctrl *curr_ctr = hdmi->plat_data->cur_ctr; + const struct sym_term *sym_term = hdmi->plat_data->sym_term; if (prep) return -EINVAL; @@ -815,10 +827,17 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, hdmi_phy_i2c_write(hdmi, 0x, 0x13); /* PLLPHBYCTRL */ hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); + + for (i = 0; sym_term[i].mpixelclock != (~0UL); i++) + if (hdmi->hdmi_data.video_mode.mpixelclock <= + sym_term[i].mpixelclock) + break; + /* RESISTANCE TERM 133Ohm Cfg */ - hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */ + hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19); /* TXTERM */ /* PREEMP Cgf 0.00 */ - hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */ + hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09); /* CKSYMTXCTRL */ + All these seem generic improvements and not rk3288 specific? Yes , different board needs different termination vale to get best SI. Do you mean we should put these in a separate patch? /* TX/CK LVL 10 */ hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */ /* REMOVE CLK TERM */ @@ -834,6 +853,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, dw_hdmi_phy_gen2_txpwron(hdmi, 1); dw_hdmi_phy_gen2_pddq(hdmi, 0); + if (hdmi->dev_type == RK3288_HDMI) + dw_hdmi_phy_enable_spare(hdmi, 1); + /*Wait for PHY PLL lock */ m
[PATCH] staging: unisys: remove testing.h
Nobody is using this file so remove it and the reference to it in visorchipset_main.c. Signed-off-by: Benjamin Romer --- drivers/staging/unisys/visorchipset/testing.h | 43 -- .../unisys/visorchipset/visorchipset_main.c| 1 - 2 files changed, 44 deletions(-) delete mode 100644 drivers/staging/unisys/visorchipset/testing.h diff --git a/drivers/staging/unisys/visorchipset/testing.h b/drivers/staging/unisys/visorchipset/testing.h deleted file mode 100644 index 573aa8b..000 --- a/drivers/staging/unisys/visorchipset/testing.h +++ /dev/null @@ -1,43 +0,0 @@ -/* testing.h - * - * Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __VISORCHIPSET_TESTING_H__ -#define __VISORCHIPSET_TESTING_H__ - -#define VISORCHIPSET_TEST_PROC -#include -#include "globals.h" -#include "controlvmchannel.h" - -void test_produce_test_message(struct controlvm_message *msg, - int isLocalTestAddr); -BOOL test_consume_test_message(struct controlvm_message *msg); -void test_manufacture_vnic_client_add(void *p); -void test_manufacture_vnic_client_add_phys(HOSTADDRESS addr); -void test_manufacture_preamble_messages(void); -void test_manufacture_device_attach(ulong busNo, ulong devNo); -void test_manufacture_device_add(ulong busNo, ulong devNo, uuid_le dataTypeGuid, -void *pChannel); -void test_manufacture_add_bus(ulong busNo, ulong maxDevices, - uuid_le id, u8 *name, BOOL isServer); -void test_manufacture_device_destroy(ulong busNo, ulong devNo); -void test_manufacture_bus_destroy(ulong busNo); -void test_manufacture_detach_externalPort(ulong switchNo, ulong externalPortNo); -void test_manufacture_detach_internalPort(ulong switchNo, ulong internalPortNo); -void test_cleanup(void); - -#endif diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index c8f7bea..0a62177 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -20,7 +20,6 @@ #include "procobjecttree.h" #include "visorchannel.h" #include "periodic_work.h" -#include "testing.h" #include "file.h" #include "parser.h" #include "uniklog.h" -- 2.1.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: unisys: fix line spacing in globals.h
Get rid of the extra blank lines in globals.h. Signed-off-by: Benjamin Romer --- drivers/staging/unisys/visorchipset/globals.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/globals.h b/drivers/staging/unisys/visorchipset/globals.h index 0fe1459..a1d35d4 100644 --- a/drivers/staging/unisys/visorchipset/globals.h +++ b/drivers/staging/unisys/visorchipset/globals.h @@ -15,7 +15,6 @@ * details. */ - #ifndef __VISORCHIPSET_GLOBALS_H__ #define __VISORCHIPSET_GLOBALS_H__ @@ -28,7 +27,6 @@ #define MYDRVNAME "visorchipset" - /* module parameters */ extern int visorchipset_testvnic; -- 2.1.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: unisys: fix line spacing in visorchipset_umode.h
Just get rid of the extra blank lines in this file. Signed-off-by: Benjamin Romer --- drivers/staging/unisys/visorchipset/visorchipset_umode.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset_umode.h b/drivers/staging/unisys/visorchipset/visorchipset_umode.h index 06ba5b7..6cf6eccb 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_umode.h +++ b/drivers/staging/unisys/visorchipset/visorchipset_umode.h @@ -26,8 +26,6 @@ #ifndef __VISORCHIPSET_UMODE_H #define __VISORCHIPSET_UMODE_H - - /** The user-mode program can access the control channel buffer directly * via this memory map. */ -- 2.1.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: unisys: get rid of channel stub
The functions in channels/* aren't used in a lot of places. In fact, the functions in channel.c can be moved to uislib/uisqueue.c, and the rest of the files in channels can be eliminated. This patch deletes the channels directory and files, removes it from all Kconfigs that referenced them, removes the reference in the Makefile, and moves the functions inside of channels.c to uislib/uisqueue.c. Signed-off-by: Benjamin Romer --- drivers/staging/unisys/Kconfig | 1 - drivers/staging/unisys/Makefile| 1 - drivers/staging/unisys/channels/Kconfig| 10 -- drivers/staging/unisys/channels/Makefile | 11 -- drivers/staging/unisys/channels/channel.c | 219 - drivers/staging/unisys/channels/chanstub.c | 75 -- drivers/staging/unisys/channels/chanstub.h | 23 --- drivers/staging/unisys/uislib/Kconfig | 2 +- drivers/staging/unisys/uislib/uislib.c | 1 - drivers/staging/unisys/uislib/uisqueue.c | 195 - drivers/staging/unisys/virthba/Kconfig | 2 +- 11 files changed, 195 insertions(+), 345 deletions(-) delete mode 100644 drivers/staging/unisys/channels/Kconfig delete mode 100644 drivers/staging/unisys/channels/Makefile delete mode 100644 drivers/staging/unisys/channels/channel.c delete mode 100644 drivers/staging/unisys/channels/chanstub.c delete mode 100644 drivers/staging/unisys/channels/chanstub.h diff --git a/drivers/staging/unisys/Kconfig b/drivers/staging/unisys/Kconfig index ac080c9..19fcb34 100644 --- a/drivers/staging/unisys/Kconfig +++ b/drivers/staging/unisys/Kconfig @@ -12,7 +12,6 @@ if UNISYSSPAR source "drivers/staging/unisys/visorutil/Kconfig" source "drivers/staging/unisys/visorchannel/Kconfig" source "drivers/staging/unisys/visorchipset/Kconfig" -source "drivers/staging/unisys/channels/Kconfig" source "drivers/staging/unisys/uislib/Kconfig" source "drivers/staging/unisys/virtpci/Kconfig" source "drivers/staging/unisys/virthba/Kconfig" diff --git a/drivers/staging/unisys/Makefile b/drivers/staging/unisys/Makefile index b988d69..68b9925 100644 --- a/drivers/staging/unisys/Makefile +++ b/drivers/staging/unisys/Makefile @@ -4,7 +4,6 @@ obj-$(CONFIG_UNISYS_VISORUTIL) += visorutil/ obj-$(CONFIG_UNISYS_VISORCHANNEL) += visorchannel/ obj-$(CONFIG_UNISYS_VISORCHIPSET) += visorchipset/ -obj-$(CONFIG_UNISYS_CHANNELSTUB) += channels/ obj-$(CONFIG_UNISYS_UISLIB)+= uislib/ obj-$(CONFIG_UNISYS_VIRTPCI) += virtpci/ obj-$(CONFIG_UNISYS_VIRTHBA) += virthba/ diff --git a/drivers/staging/unisys/channels/Kconfig b/drivers/staging/unisys/channels/Kconfig deleted file mode 100644 index 179c6ce..000 --- a/drivers/staging/unisys/channels/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -# -# Unisys channels configuration -# - -config UNISYS_CHANNELSTUB - tristate "Unisys channelstub driver" - depends on UNISYSSPAR && UNISYS_VISORUTIL - ---help--- - If you say Y here, you will enable the Unisys channels driver. - diff --git a/drivers/staging/unisys/channels/Makefile b/drivers/staging/unisys/channels/Makefile deleted file mode 100644 index adc1842..000 --- a/drivers/staging/unisys/channels/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for Unisys channelstub -# - -obj-$(CONFIG_UNISYS_CHANNELSTUB) += visorchannelstub.o - -visorchannelstub-y := channel.o chanstub.o - -ccflags-y += -Idrivers/staging/unisys/include -ccflags-y += -Idrivers/staging/unisys/common-spar/include -ccflags-y += -Idrivers/staging/unisys/common-spar/include/channels diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c deleted file mode 100644 index 74cc4d6..000 --- a/drivers/staging/unisys/channels/channel.c +++ /dev/null @@ -1,219 +0,0 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#include -#ifdef CONFIG_MODVERSIONS -#include -#endif -#include -#include /* for module_init and module_exit */ -#include /* for memcpy */ -#include - -/* Implementation of exported functions for Supervisor channels */ -#include "channel.h" - -/* - * Routine Description: - * Tries to insert the prebuilt signal pointed to by pSignal into the nth - * Queue of the Channel pointed to by pChannel - * - * Parameters: - * pChannel: (IN) points to the IO Channel - * Queue: (IN) nth Queue of the
[PATCH 11/11] staging: unisys: small bug parser.c
Fixed small bug in parser.c by removing "cleanups:" in parser_init _guts struct. Replaced it with proper error handling code and removed the instances of rc = NULL in the code. rc = NULL is redudant Signed-off-by: Jeffrey Brown --- drivers/staging/unisys/visorchipset/parser.c | 46 ++--- 1 files changed, 11 insertions(+), 35 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/parser.c b/drivers/staging/unisys/visorchipset/parser.c index 5f6a7b2..beb36a2 100644 --- a/drivers/staging/unisys/visorchipset/parser.c +++ b/drivers/staging/unisys/visorchipset/parser.c @@ -64,8 +64,6 @@ parser_init_guts(u64 addr, u32 bytes, BOOL is_local, MAX_CONTROLVM_PAYLOAD_BYTES); if (try_again) *try_again = TRUE; - rc = NULL; - goto cleanups; } ctx = kzalloc(allocbytes, GFP_KERNEL|__GFP_NORETRY); if (ctx == NULL) { @@ -73,8 +71,6 @@ parser_init_guts(u64 addr, u32 bytes, BOOL is_local, __func__, __FILE__, __LINE__, allocbytes); if (try_again) *try_again = TRUE; - rc = NULL; - goto cleanups; } ctx->allocbytes = allocbytes; @@ -89,42 +85,27 @@ parser_init_guts(u64 addr, u32 bytes, BOOL is_local, ERRDRV("%s - bad local address (0x%-16.16Lx for %lu)", __func__, (unsigned long long)addr, (ulong)bytes); - rc = NULL; - goto cleanups; } p = __va((ulong)(addr)); memcpy(ctx->data, p, bytes); } else { rgn = visor_memregion_create(addr, bytes); - if (!rgn) { - rc = NULL; - goto cleanups; - } - if (visor_memregion_read(rgn, 0, ctx->data, bytes) < 0) { - rc = NULL; - goto cleanups; - } } if (!has_standard_payload_header) { ctx->byte_stream = TRUE; rc = ctx; - goto cleanups; } phdr = (struct spar_controlvm_parameters_header *)(ctx->data); if (phdr->total_length != bytes) { ERRDRV("%s - bad total length %lu (should be %lu)", __func__, (ulong)(phdr->total_length), (ulong)(bytes)); - rc = NULL; - goto cleanups; } if (phdr->total_length < phdr->header_length) { ERRDRV("%s - total length < header length (%lu < %lu)", __func__, (ulong)(phdr->total_length), (ulong)(phdr->header_length)); - rc = NULL; - goto cleanups; } if (phdr->header_length < sizeof(struct spar_controlvm_parameters_header)) { @@ -133,25 +114,20 @@ parser_init_guts(u64 addr, u32 bytes, BOOL is_local, (ulong)(phdr->header_length), (ulong)(sizeof( struct spar_controlvm_parameters_header))); - rc = NULL; - goto cleanups; } - rc = ctx; -cleanups: - if (rgn) { +out_rgn: + if (rgn) visor_memregion_destroy(rgn); - rgn = NULL; - } - if (rc) { - controlvm_payload_bytes_buffered += ctx->param_bytes; - } else { - if (ctx) { - parser_done(ctx); - ctx = NULL; - } - } - return rc; + controlvm_payload_bytes_buffered += ctx->param_bytes; + + return ctx; +err_rgn: + if (rgn) + visor_memregion_destroy(rgn); +err_ctx: + kfree(ctx); + return NULL; } struct parser_context_tag * -- 1.7.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 1/4] staging: comedi: das6402: add basic (*do_cmdtest) for AI async commands
Currently the async command support in this driver consists of just the stubbed in functions. Flesh out the (*do_cmdtest) function for basic support of timed analog input acquisitions. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das6402.c | 105 ++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index f3909f3..29270bd 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -35,6 +35,7 @@ #include #include "../comedidev.h" +#include "comedi_fc.h" #include "8253.h" /* @@ -207,11 +208,113 @@ static int das6402_ai_cmd(struct comedi_device *dev, return -EINVAL; } +static int das6402_ai_check_chanlist(struct comedi_device *dev, +struct comedi_subdevice *s, +struct comedi_cmd *cmd) +{ + unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); + unsigned int range0 = CR_RANGE(cmd->chanlist[0]); + unsigned int aref0 = CR_AREF(cmd->chanlist[0]); + int i; + + for (i = 1; i < cmd->chanlist_len; i++) { + unsigned int chan = CR_CHAN(cmd->chanlist[i]); + unsigned int range = CR_RANGE(cmd->chanlist[i]); + unsigned int aref = CR_AREF(cmd->chanlist[i]); + + if (chan != chan0 + i) { + dev_dbg(dev->class_dev, + "chanlist must be consecutive\n"); + return -EINVAL; + } + + if (range != range0) { + dev_dbg(dev->class_dev, + "chanlist must have the same range\n"); + return -EINVAL; + } + + if (aref != aref0) { + dev_dbg(dev->class_dev, + "chanlist must have the same reference\n"); + return -EINVAL; + } + + if (aref0 == AREF_DIFF && chan > (s->n_chan / 2)) { + dev_dbg(dev->class_dev, + "chanlist differential channel to large\n"); + return -EINVAL; + } + } + return 0; +} + static int das6402_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - return -EINVAL; + struct das6402_private *devpriv = dev->private; + int err = 0; + unsigned int arg; + + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); + + if (err) + return 1; + + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ + + if (err) + return 2; + + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 1); + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else/* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + + if (err) + return 3; + + /* step 4: fix up any arguments */ + + if (cmd->convert_src == TRIG_TIMER) { + arg = cmd->convert_arg; + i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, + &devpriv->divider1, + &devpriv->divider2, + &arg, cmd->flags); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg); + } + + if (err) + return 4; + + /* Step 5: check channel list if it exists */ + if (cmd->chanlist && cmd->chanlist_len > 0) + err |= das6402_ai_check_chanlist(dev, s, cmd); + + if (err) + return 5; + + return 0; } static int das6402_ai_cancel(struct comedi_device *dev, -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject
[PATCH v2 2/4] staging: comedi: das6402: introduce das6402_ai_set_mode()
Introduce a helper function to set the analog input acquisition mode. This will be needed when the (*do_cmd) function is completed to support async commands. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das6402.c | 31 --- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 29270bd..562d6ab 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -202,6 +202,23 @@ static irqreturn_t das6402_interrupt(int irq, void *d) return IRQ_HANDLED; } +static void das6402_ai_set_mode(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int chanspec, + unsigned int mode) +{ + unsigned int range = CR_RANGE(chanspec); + unsigned int aref = CR_AREF(chanspec); + + mode |= DAS6402_MODE_RANGE(range); + if (aref == AREF_GROUND) + mode |= DAS6402_MODE_SE; + if (comedi_range_is_unipolar(s, range)) + mode |= DAS6402_MODE_UNI; + + das6402_set_mode(dev, mode); +} + static int das6402_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -349,26 +366,18 @@ static int das6402_ai_insn_read(struct comedi_device *dev, unsigned int *data) { unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int range = CR_RANGE(insn->chanspec); unsigned int aref = CR_AREF(insn->chanspec); unsigned int val; int ret; int i; - val = DAS6402_MODE_RANGE(range) | DAS6402_MODE_POLLED; - if (aref == AREF_DIFF) { - if (chan > s->n_chan / 2) - return -EINVAL; - } else { - val |= DAS6402_MODE_SE; - } - if (comedi_range_is_unipolar(s, range)) - val |= DAS6402_MODE_UNI; + if (aref == AREF_DIFF && chan > (s->n_chan / 2)) + return -EINVAL; /* enable software conversion trigger */ outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG); - das6402_set_mode(dev, val); + das6402_ai_set_mode(dev, s, insn->chanspec, DAS6402_MODE_POLLED); /* load the mux for single channel conversion */ outw(DAS6402_AI_MUX_HI(chan) | DAS6402_AI_MUX_LO(chan), -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 4/4] staging: comedi: das6402: add (*do_cmd) for AI async commands
Flesh out the (*do_cmd) function to support timed analog input acquisitions. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das6402.c | 20 +++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 047e973..780f4f6 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -256,7 +256,25 @@ static void das6402_ai_set_mode(struct comedi_device *dev, static int das6402_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - return -EINVAL; + struct das6402_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int chan_lo = CR_CHAN(cmd->chanlist[0]); + unsigned int chan_hi = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]); + + das6402_ai_set_mode(dev, s, cmd->chanlist[0], DAS6402_MODE_FIFONEPTY); + + /* load the mux for chanlist conversion */ + outw(DAS6402_AI_MUX_HI(chan_hi) | DAS6402_AI_MUX_LO(chan_lo), +dev->iobase + DAS6402_AI_MUX_REG); + + das6402_enable_counter(dev, true); + + /* enable interrupt and pacer trigger */ + outb(DAS6402_CTRL_INTE | +DAS6402_CTRL_IRQ(devpriv->irq) | +DAS6402_CTRL_PACER_TRIG, dev->iobase + DAS6402_CTRL_REG); + + return 0; } static int das6402_ai_check_chanlist(struct comedi_device *dev, -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 0/4] staging: comedi: das6402: add basic AI async command support
This series adds support for basic AI async commands. v2: fix a debug message in PATCH 1/4 pointed out by Ian Abbott. H Hartley Sweeten (4): staging: comedi: das6402: add basic (*do_cmdtest) for AI async commands staging: comedi: das6402: introduce das6402_ai_set_mode() staging: comedi: das6402: read analog input samples in interrupt handler staging: comedi: das6402: add (*do_cmd) for AI async commands drivers/staging/comedi/drivers/das6402.c | 198 +++ 1 file changed, 178 insertions(+), 20 deletions(-) -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 3/4] staging: comedi: das6402: read analog input samples in interrupt handler
Currently the interrupt handler just clears the interrupt. Add the code necessary to read the analog input samples when running an async command. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Cc: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das6402.c | 42 ++-- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 562d6ab..047e973 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -193,12 +193,46 @@ static void das6402_enable_counter(struct comedi_device *dev, bool load) } } +static unsigned int das6402_ai_read_sample(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + unsigned int val; + + val = inw(dev->iobase + DAS6402_AI_DATA_REG); + if (s->maxdata == 0x0fff) + val >>= 4; + return val; +} + static irqreturn_t das6402_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + unsigned int status; + + status = inb(dev->iobase + DAS6402_STATUS_REG); + if ((status & DAS6402_STATUS_INT) == 0) + return IRQ_NONE; + + if (status & DAS6402_STATUS_FFULL) { + async->events |= COMEDI_CB_OVERFLOW; + } else if (status & DAS6402_STATUS_FFNE) { + unsigned int val; + + val = das6402_ai_read_sample(dev, s); + comedi_buf_write_samples(s, &val, 1); + + if (cmd->stop_src == TRIG_COUNT && + async->scans_done >= cmd->stop_arg) + async->events |= COMEDI_CB_EOA; + } das6402_clear_all_interrupts(dev); + comedi_handle_events(dev, s); + return IRQ_HANDLED; } @@ -367,7 +401,6 @@ static int das6402_ai_insn_read(struct comedi_device *dev, { unsigned int chan = CR_CHAN(insn->chanspec); unsigned int aref = CR_AREF(insn->chanspec); - unsigned int val; int ret; int i; @@ -391,12 +424,7 @@ static int das6402_ai_insn_read(struct comedi_device *dev, if (ret) break; - val = inw(dev->iobase + DAS6402_AI_DATA_REG); - - if (s->maxdata == 0x0fff) - val >>= 4; - - data[i] = val; + data[i] = das6402_ai_read_sample(dev, s); } das6402_ai_clear_eoc(dev); -- 2.0.3 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[RFC PATCH 00/16] Replace smp_read_barrier_depends() with lockless_derefrence()
Recently lockless_dereference() was added which can be used in place of hard-coding smp_read_barrier_depends(). http://lkml.iu.edu/hypermail/linux/kernel/1410.3/04561.html The following series tries to do this. There are still some hard-coded locations which I was not sure how to replace with. I will send in separate patches/questions regarding them. Pranith Kumar (16): crypto: caam - Remove unnecessary smp_read_barrier_depends() doc: memory-barriers.txt: Document use of lockless_dereference() drivers: dma: Replace smp_read_barrier_depends() with lockless_dereference() dcache: Replace smp_read_barrier_depends() with lockless_dereference() overlayfs: Replace smp_read_barrier_depends() with lockless_dereference() assoc_array: Replace smp_read_barrier_depends() with lockless_dereference() hyperv: Replace smp_read_barrier_depends() with lockless_dereference() rcupdate: Replace smp_read_barrier_depends() with lockless_dereference() percpu: Replace smp_read_barrier_depends() with lockless_dereference() perf: Replace smp_read_barrier_depends() with lockless_dereference() seccomp: Replace smp_read_barrier_depends() with lockless_dereference() task_work: Replace smp_read_barrier_depends() with lockless_dereference() ksm: Replace smp_read_barrier_depends() with lockless_dereference() slab: Replace smp_read_barrier_depends() with lockless_dereference() netfilter: Replace smp_read_barrier_depends() with lockless_dereference() rxrpc: Replace smp_read_barrier_depends() with lockless_dereference() Documentation/memory-barriers.txt | 2 +- drivers/crypto/caam/jr.c | 3 --- drivers/dma/ioat/dma_v2.c | 3 +-- drivers/dma/ioat/dma_v3.c | 3 +-- fs/dcache.c | 7 ++- fs/overlayfs/super.c | 4 +--- include/linux/assoc_array_priv.h | 11 +++ include/linux/hyperv.h| 9 - include/linux/percpu-refcount.h | 4 +--- include/linux/rcupdate.h | 10 +- kernel/events/core.c | 3 +-- kernel/events/uprobes.c | 8 kernel/seccomp.c | 7 +++ kernel/task_work.c| 3 +-- lib/assoc_array.c | 7 --- mm/ksm.c | 7 +++ mm/slab.h | 6 +++--- net/ipv4/netfilter/arp_tables.c | 3 +-- net/ipv4/netfilter/ip_tables.c| 3 +-- net/ipv6/netfilter/ip6_tables.c | 3 +-- net/rxrpc/ar-ack.c| 22 +- security/keys/keyring.c | 6 -- 22 files changed, 50 insertions(+), 84 deletions(-) -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 07/16] hyperv: Replace smp_read_barrier_depends() with lockless_dereference()
Recently lockless_dereference() was added which can be used in place of hard-coding smp_read_barrier_depends(). The following PATCH makes the change. Signed-off-by: Pranith Kumar --- include/linux/hyperv.h | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 08cfaff..06418b1 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -127,13 +127,12 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, u32 *read, u32 *write) { u32 read_loc, write_loc, dsize; - - smp_read_barrier_depends(); + struct hv_ring_buffer_info *rbi_p = lockless_dereference(rbi); /* Capture the read/write indices before they changed */ - read_loc = rbi->ring_buffer->read_index; - write_loc = rbi->ring_buffer->write_index; - dsize = rbi->ring_datasize; + read_loc = rbi_p->ring_buffer->read_index; + write_loc = rbi_p->ring_buffer->write_index; + dsize = rbi_p->ring_datasize; *write = write_loc >= read_loc ? dsize - (write_loc - read_loc) : read_loc - write_loc; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [RFC PATCH 00/16] Replace smp_read_barrier_depends() with lockless_derefrence()
On Thu, Nov 13, 2014 at 02:24:06PM -0500, Pranith Kumar wrote: > Recently lockless_dereference() was added which can be used in place of > hard-coding smp_read_barrier_depends(). > > http://lkml.iu.edu/hypermail/linux/kernel/1410.3/04561.html > > The following series tries to do this. > > There are still some hard-coded locations which I was not sure how to replace > with. I will send in separate patches/questions regarding them. Thank you for taking this on! Some questions and comments in response to the individual patches. Thanx, Paul > Pranith Kumar (16): > crypto: caam - Remove unnecessary smp_read_barrier_depends() > doc: memory-barriers.txt: Document use of lockless_dereference() > drivers: dma: Replace smp_read_barrier_depends() with > lockless_dereference() > dcache: Replace smp_read_barrier_depends() with lockless_dereference() > overlayfs: Replace smp_read_barrier_depends() with > lockless_dereference() > assoc_array: Replace smp_read_barrier_depends() with > lockless_dereference() > hyperv: Replace smp_read_barrier_depends() with lockless_dereference() > rcupdate: Replace smp_read_barrier_depends() with > lockless_dereference() > percpu: Replace smp_read_barrier_depends() with lockless_dereference() > perf: Replace smp_read_barrier_depends() with lockless_dereference() > seccomp: Replace smp_read_barrier_depends() with > lockless_dereference() > task_work: Replace smp_read_barrier_depends() with > lockless_dereference() > ksm: Replace smp_read_barrier_depends() with lockless_dereference() > slab: Replace smp_read_barrier_depends() with lockless_dereference() > netfilter: Replace smp_read_barrier_depends() with > lockless_dereference() > rxrpc: Replace smp_read_barrier_depends() with lockless_dereference() > > Documentation/memory-barriers.txt | 2 +- > drivers/crypto/caam/jr.c | 3 --- > drivers/dma/ioat/dma_v2.c | 3 +-- > drivers/dma/ioat/dma_v3.c | 3 +-- > fs/dcache.c | 7 ++- > fs/overlayfs/super.c | 4 +--- > include/linux/assoc_array_priv.h | 11 +++ > include/linux/hyperv.h| 9 - > include/linux/percpu-refcount.h | 4 +--- > include/linux/rcupdate.h | 10 +- > kernel/events/core.c | 3 +-- > kernel/events/uprobes.c | 8 > kernel/seccomp.c | 7 +++ > kernel/task_work.c| 3 +-- > lib/assoc_array.c | 7 --- > mm/ksm.c | 7 +++ > mm/slab.h | 6 +++--- > net/ipv4/netfilter/arp_tables.c | 3 +-- > net/ipv4/netfilter/ip_tables.c| 3 +-- > net/ipv6/netfilter/ip6_tables.c | 3 +-- > net/rxrpc/ar-ack.c| 22 +- > security/keys/keyring.c | 6 -- > 22 files changed, 50 insertions(+), 84 deletions(-) > > -- > 1.9.1 > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 05/56] fs/lustre: support compiling out splice
Compile out splice support from lustre file-system when the splice-family of syscalls is not supported by the system (i.e. CONFIG_SYSCALL_SPLICE is undefined). Signed-off-by: Pieter Smith --- drivers/staging/lustre/lustre/llite/file.c | 10 +++--- drivers/staging/lustre/lustre/llite/llite_internal.h | 2 ++ drivers/staging/lustre/lustre/llite/vvp_io.c | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index fd1b75a3..98573da 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1126,10 +1126,12 @@ restart: down_read(&lli->lli_trunc_sem); } break; +#ifdef CONFIG_SYSCALL_SPLICE case IO_SPLICE: vio->u.splice.cui_pipe = args->u.splice.via_pipe; vio->u.splice.cui_flags = args->u.splice.via_flags; break; +#endif /* #ifdef CONFIG_SYSCALL_SPLICE */ default: CERROR("Unknown IO type - %u\n", vio->cui_io_subtype); LBUG(); @@ -1223,6 +1225,7 @@ static ssize_t ll_file_write_iter(struct kiocb *iocb, struct iov_iter *from) return result; } +#ifdef CONFIG_SYSCALL_SPLICE /* * Send file content (through pagecache) somewhere with helper */ @@ -1247,6 +1250,7 @@ static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos, cl_env_put(env, &refcheck); return result; } +#endif /* #ifdef CONFIG_SYSCALL_SPLICE */ static int ll_lov_recreate(struct inode *inode, struct ost_id *oi, obd_count ost_idx) @@ -3078,7 +3082,7 @@ struct file_operations ll_file_operations = { .release= ll_file_release, .mmap = ll_file_mmap, .llseek = ll_file_seek, - .splice_read= ll_file_splice_read, + SPLICE_READ_INIT(ll_file_splice_read) .fsync= ll_fsync, .flush= ll_flush }; @@ -3093,7 +3097,7 @@ struct file_operations ll_file_operations_flock = { .release= ll_file_release, .mmap = ll_file_mmap, .llseek = ll_file_seek, - .splice_read= ll_file_splice_read, + SPLICE_READ_INIT(ll_file_splice_read) .fsync= ll_fsync, .flush= ll_flush, .flock= ll_file_flock, @@ -3111,7 +3115,7 @@ struct file_operations ll_file_operations_noflock = { .release= ll_file_release, .mmap = ll_file_mmap, .llseek = ll_file_seek, - .splice_read= ll_file_splice_read, + SPLICE_READ_INIT(ll_file_splice_read) .fsync= ll_fsync, .flush= ll_flush, .flock= ll_file_noflock, diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 634ffa6..44fa32a 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -861,7 +861,9 @@ enum vvp_io_subtype { /** normal IO */ IO_NORMAL, /** io started from splice_{read|write} */ +#ifdef CONFIG_SYSCALL_SPLICE IO_SPLICE +#endif /* #ifdef CONFIG_SYSCALL_SPLICE */ }; /* IO subtypes */ diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index a4117d6..2f4aa39 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -530,6 +530,7 @@ static int vvp_io_read_start(const struct lu_env *env, LASSERT(cio->cui_iocb->ki_pos == pos); result = generic_file_read_iter(cio->cui_iocb, cio->cui_iter); break; +#ifdef CONFIG_SYSCALL_SPLICE case IO_SPLICE: result = generic_file_splice_read(file, &pos, vio->u.splice.cui_pipe, cnt, @@ -539,6 +540,7 @@ static int vvp_io_read_start(const struct lu_env *env, * buffers. */ io->ci_continue = 0; break; +#endif /* #ifdef CONFIG_SYSCALL_SPLICE */ default: CERROR("Wrong IO type %u\n", vio->cui_io_subtype); LBUG(); -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 05/56] fs/lustre: support compiling out splice
On Thu, Nov 13, 2014 at 10:22:42PM +0100, Pieter Smith wrote: > Compile out splice support from lustre file-system when the splice-family of > syscalls is not supported by the system (i.e. CONFIG_SYSCALL_SPLICE is > undefined). > > Signed-off-by: Pieter Smith > --- > drivers/staging/lustre/lustre/llite/file.c | 10 +++--- > drivers/staging/lustre/lustre/llite/llite_internal.h | 2 ++ > drivers/staging/lustre/lustre/llite/vvp_io.c | 2 ++ > 3 files changed, 11 insertions(+), 3 deletions(-) > > diff --git a/drivers/staging/lustre/lustre/llite/file.c > b/drivers/staging/lustre/lustre/llite/file.c > index fd1b75a3..98573da 100644 > --- a/drivers/staging/lustre/lustre/llite/file.c > +++ b/drivers/staging/lustre/lustre/llite/file.c > @@ -1126,10 +1126,12 @@ restart: > down_read(&lli->lli_trunc_sem); > } > break; > +#ifdef CONFIG_SYSCALL_SPLICE > case IO_SPLICE: > vio->u.splice.cui_pipe = args->u.splice.via_pipe; > vio->u.splice.cui_flags = args->u.splice.via_flags; > break; > +#endif /* #ifdef CONFIG_SYSCALL_SPLICE */ Not worth the #ifdef mess, sorry. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: Why does ion_cma_allocate need GFP_HIGHUSER | __GFP_ZERO flags?
On 11/12/2014 11:18 PM, Gioh Kim wrote: > Hi, > > I'm wondering why dma_alloc_coherent needs GFP_HIGHUSER | __GFP_ZERO flags in > ion_cma_allocate(). > > I think dma_alloc_coherent can go to __dma_alloc if the system has CMA area. > If __GFP_WAIT flag is set, it allocates memory from atomic pool. > So I think calling dma_alloc_coherent with __GFP_WAIT is enough. > > And can I get zero-filled-memory from CMA if I set __GFP_ZERO? > > If we are actually using CMA, the GFP flags don't make much of a difference. If we didn't have CMA, using GFP_HIGHUSER would still be appropriate. The memory is going to userspace so the user part is necessary and there should be no need for a lowmem mapping so highmem can be used. __GFP_ZERO might be redundant since the dma layer zeros memory anyway but it's probably safe. I think the flags should be fine as is. Thanks, Laura -- Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: Why does ion_cma_allocate need GFP_HIGHUSER | __GFP_ZERO flags?
2014-11-14 오전 10:24에 Laura Abbott 이(가) 쓴 글: > On 11/12/2014 11:18 PM, Gioh Kim wrote: >> Hi, >> >> I'm wondering why dma_alloc_coherent needs GFP_HIGHUSER | __GFP_ZERO flags >> in ion_cma_allocate(). >> >> I think dma_alloc_coherent can go to __dma_alloc if the system has CMA area. >> If __GFP_WAIT flag is set, it allocates memory from atomic pool. >> So I think calling dma_alloc_coherent with __GFP_WAIT is enough. >> >> And can I get zero-filled-memory from CMA if I set __GFP_ZERO? >> >> > > If we are actually using CMA, the GFP flags don't make much of a difference. > If > we didn't have CMA, using GFP_HIGHUSER would still be appropriate. The memory > is going to userspace so the user part is necessary and there should be no > need > for a lowmem mapping so highmem can be used. __GFP_ZERO might be redundant > since > the dma layer zeros memory anyway but it's probably safe. If cma-heap can be created even-if the system doesn't have CMA area, you're right. But I think cma-heap should be created only if the system has CMA area. I think, in no CMA system, cma-heap creation and/or allocation from cma-heap should be failed, not allocate memory from lowmem or highmem as you say. Thanks for your reply. > > I think the flags should be fine as is. > > Thanks, > Laura > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v10 0/11] dw-hdmi: convert imx hdmi to bridge/dw_hdmi
We found Freescale imx6 and Rockchip rk3288 and Ingenic JZ4780 (Xburst/MIPS) use the interface compatible Designware HDMI IP, but they also have some lightly differences, such as phy pll configuration, register width(imx hdmi register is one byte, but rk3288 is 4 bytes width and can only be accessed by word), 4K support(imx6 doesn't support 4k, but rk3288 does), and HDMI2.0 support. To reuse the imx-hdmi driver, we make this patch set: (1): fix some CodingStyle warning to make checkpatch happy (2): split out imx-soc code from imx-hdmi to dw_hdmi-imx.c (3): move imx-hdmi to bridge/dw-hdmi, and convert it to a drm_bridge driver (4): add rockchip rk3288 platform specific code dw_hdmi-rockchip.c Changes in v10: - split generic dw_hdmi.c improvements from patch#11(add rk3288 support) - add more display mode support mpll configuration for rk3288 Changes in v9: - move some phy configuration to platform driver Changes in v8: - correct some spelling mistake - modify ddc-i2c-bus and interrupt description - Add documentation for rockchip dw hdmi Changes in v7: - remove unused variables from structure dw_hdmi - remove a wrong modification - add copyrights for dw_hdmi-imx.c Changes in v6: - rearrange the patch order - move some modification to patch#6 - refactor register access without reg_shift - move some modification from patch#5 Changes in v5: - refactor reg-io-width Changes in v4: - fix checkpatch CHECK - defer probe ddc i2c adapter Changes in v3: - split multi register access to one indepent patch Changes in v2: - use git format -M to generate these patch Andy Yan (10): staging: imx-drm: imx-hdmi: make checkpatch happy staging: imx-drm: imx-hdmi: return defer if can't get ddc i2c adapter staging: imx-drm: imx-hdmi: split imx soc specific code from imx-hdmi staging: imx-drm: imx-hdmi: move imx-hdmi to bridge/dw_hdmi drm: bridge/dw_hdmi:split some phy configuration to platform driver drm: bridge/dw_hdmi: clear i2cmphy_stat0 reg in hdmi_phy_wait_i2c_done dt-bindings: add document for dw_hdmi drm: bridge/dw_hdmi: add support for multi byte register width access dt-bindings: Add documentation for rockchip dw hdmi drm: bridge/dw_hdmi: add rockchip rk3288 support Yakir Yang (1): drm: bridge/dw_hdmi: convert dw-hdmi to drm_bridge mode .../devicetree/bindings/drm/bridge/dw_hdmi.txt | 40 ++ .../devicetree/bindings/video/dw_hdmi-rockchip.txt | 43 ++ drivers/gpu/drm/bridge/Kconfig | 5 + drivers/gpu/drm/bridge/Makefile| 1 + .../imx-hdmi.c => gpu/drm/bridge/dw_hdmi.c}| 762 + .../imx-hdmi.h => gpu/drm/bridge/dw_hdmi.h}| 8 +- drivers/gpu/drm/rockchip/Kconfig | 10 + drivers/gpu/drm/rockchip/Makefile | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 355 ++ drivers/staging/imx-drm/Kconfig| 1 + drivers/staging/imx-drm/Makefile | 2 +- drivers/staging/imx-drm/dw_hdmi-imx.c | 274 include/drm/bridge/dw_hdmi.h | 60 ++ 13 files changed, 1138 insertions(+), 425 deletions(-) create mode 100644 Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt create mode 100644 Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt rename drivers/{staging/imx-drm/imx-hdmi.c => gpu/drm/bridge/dw_hdmi.c} (70%) rename drivers/{staging/imx-drm/imx-hdmi.h => gpu/drm/bridge/dw_hdmi.h} (99%) create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c create mode 100644 drivers/staging/imx-drm/dw_hdmi-imx.c create mode 100644 include/drm/bridge/dw_hdmi.h -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v10 01/11] staging: imx-drm: imx-hdmi: make checkpatch happy
CHECK: Alignment should match open parenthesis + if ((hdmi->vic == 10) || (hdmi->vic == 11) || + (hdmi->vic == 12) || (hdmi->vic == 13) || CHECK: braces {} should be used on all arms of this statement + if (hdmi->hdmi_data.video_mode.mdvi) [...] + else { [...] Signed-off-by: Andy Yan --- Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: - rearrange the patch order Changes in v5: None Changes in v4: - fix checkpatch CHECK Changes in v3: None Changes in v2: None drivers/staging/imx-drm/imx-hdmi.c | 97 +++--- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index aaec6b2..79daec4 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -163,7 +163,7 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) } static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, - u8 shift, u8 mask) +u8 shift, u8 mask) { hdmi_modb(hdmi, data << shift, mask, reg); } @@ -327,7 +327,7 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, } static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi, - unsigned long pixel_clk) +unsigned long pixel_clk) { unsigned int clk_n, clk_cts; @@ -338,7 +338,7 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi, if (!clk_cts) { dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", -__func__, pixel_clk); + __func__, pixel_clk); return; } @@ -477,13 +477,11 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) u16 coeff_b = (*csc_coeff)[1][i]; u16 coeff_c = (*csc_coeff)[2][i]; - hdmi_writeb(hdmi, coeff_a & 0xff, - HDMI_CSC_COEF_A1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2); hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); - hdmi_writeb(hdmi, coeff_c & 0xff, - HDMI_CSC_COEF_C1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2); hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); } @@ -535,21 +533,22 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; u8 val, vp_conf; - if (hdmi_data->enc_out_format == RGB - || hdmi_data->enc_out_format == YCBCR444) { - if (!hdmi_data->enc_color_depth) + if (hdmi_data->enc_out_format == RGB || + hdmi_data->enc_out_format == YCBCR444) { + if (!hdmi_data->enc_color_depth) { output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; - else if (hdmi_data->enc_color_depth == 8) { + } else if (hdmi_data->enc_color_depth == 8) { color_depth = 4; output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; - } else if (hdmi_data->enc_color_depth == 10) + } else if (hdmi_data->enc_color_depth == 10) { color_depth = 5; - else if (hdmi_data->enc_color_depth == 12) + } else if (hdmi_data->enc_color_depth == 12) { color_depth = 6; - else if (hdmi_data->enc_color_depth == 16) + } else if (hdmi_data->enc_color_depth == 16) { color_depth = 7; - else + } else { return; + } } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { if (!hdmi_data->enc_color_depth || hdmi_data->enc_color_depth == 8) @@ -561,8 +560,9 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) else return; output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; - } else + } else { return; + } /* set the packetizer registers */ val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & @@ -623,34 +623,34 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) } static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi, - unsigned char bit) + unsigned char bit) { hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET, HDMI_PHY_TS
[PATCH v10 02/11] staging: imx-drm: imx-hdmi: return defer if can't get ddc i2c adapter
drm driver may probe before the i2c bus, so the driver should defer probing until it is available Signed-off-by: Andy Yan --- Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: - defer probe ddc i2c adapter Changes in v3: None Changes in v2: None drivers/staging/imx-drm/imx-hdmi.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 79daec4..c2b035a 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1611,8 +1611,11 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); - if (!hdmi->ddc) + if (!hdmi->ddc) { dev_dbg(hdmi->dev, "failed to read ddc node\n"); + of_node_put(ddc_node); + return -EPROBE_DEFER; + } of_node_put(ddc_node); } else { -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v10 03/11] staging: imx-drm: imx-hdmi: split imx soc specific code from imx-hdmi
IMX6 and Rockchip RK3288 and JZ4780 (Ingenic Xburst/MIPS) use the interface compatible Designware HDMI IP, but they also have some lightly differences, such as phy pll configuration, register width, 4K support, clk useage, and the crtc mux configuration is also platform specific. To reuse the imx hdmi driver, split the platform specific code out to dw_hdmi-imx.c. Signed-off-by: Andy Yan --- Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: - remove unused variables from structure dw_hdmi - remove a wrong modification - add copyrights for dw_hdmi-imx.c Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/staging/imx-drm/Makefile | 2 +- drivers/staging/imx-drm/dw_hdmi-imx.c | 217 + drivers/staging/imx-drm/imx-hdmi.c| 255 -- drivers/staging/imx-drm/imx-hdmi.h| 43 ++ 4 files changed, 322 insertions(+), 195 deletions(-) create mode 100644 drivers/staging/imx-drm/dw_hdmi-imx.c diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index 582c438..809027d 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -9,4 +9,4 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o obj-$(CONFIG_DRM_IMX_IPUV3)+= imx-ipuv3-crtc.o -obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o +obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o dw_hdmi-imx.o diff --git a/drivers/staging/imx-drm/dw_hdmi-imx.c b/drivers/staging/imx-drm/dw_hdmi-imx.c new file mode 100644 index 000..0db978e --- /dev/null +++ b/drivers/staging/imx-drm/dw_hdmi-imx.c @@ -0,0 +1,217 @@ +/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. + * + * derived from imx-hdmi.c(renamed to bridge/dw_hdmi.c now) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "imx-drm.h" +#include "imx-hdmi.h" + +struct imx_hdmi_priv { + struct device *dev; + struct clk *isfr_clk; + struct clk *iahb_clk; + struct regmap *regmap; +}; + +static const struct mpll_config imx_mpll_cfg[] = { + { + 4525, { + { 0x01e0, 0x }, + { 0x21e1, 0x }, + { 0x41e2, 0x } + }, + }, { + 9250, { + { 0x0140, 0x0005 }, + { 0x2141, 0x0005 }, + { 0x4142, 0x0005 }, + }, + }, { + 14850, { + { 0x00a0, 0x000a }, + { 0x20a1, 0x000a }, + { 0x40a2, 0x000a }, + }, + }, { + ~0UL, { + { 0x00a0, 0x000a }, + { 0x2001, 0x000f }, + { 0x4002, 0x000f }, + }, + } +}; + +static const struct curr_ctrl imx_cur_ctr[] = { + /* pixelclk bpp8bpp10 bpp12 */ + { + 5400, { 0x091c, 0x091c, 0x06dc }, + }, { + 5840, { 0x091c, 0x06dc, 0x06dc }, + }, { + 7200, { 0x06dc, 0x06dc, 0x091c }, + }, { + 7425, { 0x06dc, 0x0b5c, 0x091c }, + }, { + 11880, { 0x091c, 0x091c, 0x06dc }, + }, { + 21600, { 0x06dc, 0x0b5c, 0x091c }, + } +}; + +static int imx_hdmi_parse_dt(struct imx_hdmi_priv *hdmi) +{ + struct device_node *np = hdmi->dev->of_node; + + hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); + if (IS_ERR(hdmi->regmap)) { + dev_err(hdmi->dev, "Unable to get gpr\n"); + return PTR_ERR(hdmi->regmap); + } + + hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); + if (IS_ERR(hdmi->isfr_clk)) { + dev_err(hdmi->dev, "Unable to get HDMI isfr clk\n"); + return PTR_ERR(hdmi->isfr_clk); + } + + hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); + if (IS_ERR(hdmi->iahb_clk)) { + dev_err(hdmi->dev, "Unable to get HDMI iahb clk\n"); + return PTR_ERR(hdmi->iahb_clk); + } + + return 0; +} + +static void *imx_hdmi_imx_setup(struct platform_device *pdev) +{ + struct imx_hdmi_priv *hdmi; + int ret; + + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return ERR_PTR(-ENOMEM); + hdmi->dev = &pdev->dev; + + ret = imx_hdmi_parse_dt(hdmi); + if (ret < 0) + return ERR_PTR(ret); + ret = clk_prepare_enable(hdmi->isfr_clk); + if (ret) { + dev_err(hdmi->dev, + "Cannot enable HDMI isfr
[PATCH v10 04/11] staging: imx-drm: imx-hdmi: move imx-hdmi to bridge/dw_hdmi
the original imx hdmi driver is under staging/imx-drm, which depends on imx-drm, so move the imx hdmi driver out to drm/bridge and rename imx-hdmi to dw_hdmi Signed-off-by: Andy Yan --- Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: - use git format -M to generate these patch drivers/gpu/drm/bridge/Kconfig | 5 + drivers/gpu/drm/bridge/Makefile| 1 + .../imx-hdmi.c => gpu/drm/bridge/dw_hdmi.c}| 281 +++-- .../imx-hdmi.h => gpu/drm/bridge/dw_hdmi.h}| 46 +--- drivers/staging/imx-drm/Kconfig| 1 + drivers/staging/imx-drm/Makefile | 2 +- drivers/staging/imx-drm/dw_hdmi-imx.c | 70 ++--- include/drm/bridge/dw_hdmi.h | 57 + 8 files changed, 243 insertions(+), 220 deletions(-) rename drivers/{staging/imx-drm/imx-hdmi.c => gpu/drm/bridge/dw_hdmi.c} (83%) rename drivers/{staging/imx-drm/imx-hdmi.h => gpu/drm/bridge/dw_hdmi.h} (97%) create mode 100644 include/drm/bridge/dw_hdmi.h diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 884923f..26162ef 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -3,3 +3,8 @@ config DRM_PTN3460 depends on DRM select DRM_KMS_HELPER ---help--- + +config DRM_DW_HDMI + bool "Synopsys DesignWare High-Definition Multimedia Interface" + depends on DRM + select DRM_KMS_HELPER diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index b4733e1..d8a8cfd 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -1,3 +1,4 @@ ccflags-y := -Iinclude/drm obj-$(CONFIG_DRM_PTN3460) += ptn3460.o +obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c similarity index 83% rename from drivers/staging/imx-drm/imx-hdmi.c rename to drivers/gpu/drm/bridge/dw_hdmi.c index c7e5f12..e9f0dfe 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -6,8 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * SH-Mobile High-Definition Multimedia Interface (HDMI) driver - * for SLISHDMI13T and SLIPHDMIT IP cores + * Designware High-Definition Multimedia Interface (HDMI) driver * * Copyright (C) 2010, Guennadi Liakhovetski */ @@ -24,8 +23,9 @@ #include #include #include +#include -#include "imx-hdmi.h" +#include "dw_hdmi.h" #define HDMI_EDID_LEN 512 @@ -101,15 +101,15 @@ struct hdmi_data_info { struct hdmi_vmode video_mode; }; -struct imx_hdmi { +struct dw_hdmi { struct drm_connector connector; struct drm_encoder encoder; - enum imx_hdmi_devtype dev_type; + enum dw_hdmi_devtype dev_type; struct device *dev; struct hdmi_data_info hdmi_data; - const struct imx_hdmi_plat_data *plat_data; + const struct dw_hdmi_plat_data *plat_data; void *priv; int vic; @@ -127,17 +127,17 @@ struct imx_hdmi { int ratio; }; -static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset) +static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) { writeb(val, hdmi->regs + offset); } -static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset) +static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) { return readb(hdmi->regs + offset); } -static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) +static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) { u8 val = hdmi_readb(hdmi, reg) & ~mask; @@ -145,13 +145,13 @@ static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) hdmi_writeb(hdmi, val, reg); } -static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, +static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg, u8 shift, u8 mask) { hdmi_modb(hdmi, data << shift, mask, reg); } -static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, +static void hdmi_set_clock_regenerator_n(struct dw_hdmi *hdmi, unsigned int value) { hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1); @@ -162,7 +162,7 @@ static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); } -static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts) +static void hdmi_regenerate_cts(struct dw_hdmi *hdmi, unsigned int cts) { /* Must be set/cleared first */ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); @@ -309,7 +309,7 @@ static unsig
[PATCH v10 05/11] drm: bridge/dw_hdmi:split some phy configuration to platform driver
hdmi phy clock symbol and transmission termination value can adjust platform specific to get the best SI also add mode_valid interface for some platform may not support all the display mode Signed-off-by: Andy Yan --- Changes in v10: - split generic dw_hdmi.c improvements from patch#11 (add rk3288 support) Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c | 29 +++-- drivers/staging/imx-drm/dw_hdmi-imx.c | 10 +- include/drm/bridge/dw_hdmi.h | 7 +++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index e9f0dfe..05e7156 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -718,6 +718,7 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, u8 val, msec; const struct mpll_config *mpll_cfg = hdmi->plat_data->mpll_cfg; const struct curr_ctrl *curr_ctr = hdmi->plat_data->cur_ctr; + const struct sym_term *sym_term = hdmi->plat_data->sym_term; if (prep) return -EINVAL; @@ -787,10 +788,17 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, hdmi_phy_i2c_write(hdmi, 0x, 0x13); /* PLLPHBYCTRL */ hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); + + for (i = 0; sym_term[i].mpixelclock != (~0UL); i++) + if (hdmi->hdmi_data.video_mode.mpixelclock <= + sym_term[i].mpixelclock) + break; + /* RESISTANCE TERM 133Ohm Cfg */ - hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */ + hdmi_phy_i2c_write(hdmi, sym_term[i].term, 0x19); /* TXTERM */ /* PREEMP Cgf 0.00 */ - hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */ + hdmi_phy_i2c_write(hdmi, sym_term[i].sym_ctr, 0x09); /* CKSYMTXCTRL */ + /* TX/CK LVL 10 */ hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */ /* REMOVE CLK TERM */ @@ -1326,6 +1334,20 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) return 0; } +static enum drm_mode_status +dw_hdmi_connector_mode_valid(struct drm_connector *connector, +struct drm_display_mode *mode) +{ + struct dw_hdmi *hdmi = container_of(connector, + struct dw_hdmi, connector); + enum drm_mode_status mode_status = MODE_OK; + + if (hdmi->plat_data->mode_valid) + mode_status = hdmi->plat_data->mode_valid(connector, mode); + + return mode_status; +} + static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector *connector) { @@ -1416,6 +1438,7 @@ static struct drm_connector_funcs dw_hdmi_connector_funcs = { static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = { .get_modes = dw_hdmi_connector_get_modes, + .mode_valid = dw_hdmi_connector_mode_valid, .best_encoder = dw_hdmi_connector_best_encoder, }; @@ -1487,6 +1510,8 @@ static int dw_hdmi_register(struct drm_device *drm, struct dw_hdmi *hdmi) drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder); + drm_connector_register(&hdmi->connector); + return 0; } diff --git a/drivers/staging/imx-drm/dw_hdmi-imx.c b/drivers/staging/imx-drm/dw_hdmi-imx.c index 4b48ea6..d693051 100644 --- a/drivers/staging/imx-drm/dw_hdmi-imx.c +++ b/drivers/staging/imx-drm/dw_hdmi-imx.c @@ -69,7 +69,13 @@ static const struct curr_ctrl imx_cur_ctr[] = { } }; -static int dw_hdmi_parse_dt(struct imx_hdmi *hdmi) +static const struct sym_term imx_sym_term[] = { + /*pixelclk symbol term*/ + { 14850, 0x800d, 0x0005 }, + { ~0UL, 0x, 0x } +}; + +static int dw_hdmi_imx_parse_dt(struct imx_hdmi *hdmi) { struct device_node *np = hdmi->dev->of_node; @@ -156,6 +162,7 @@ static struct dw_hdmi_plat_data imx6q_hdmi_drv_data = { .encoder_prepare= dw_hdmi_imx_encoder_prepare, .mpll_cfg = imx_mpll_cfg, .cur_ctr= imx_cur_ctr, + .sym_term = imx_sym_term, .dev_type = IMX6Q_HDMI, }; @@ -166,6 +173,7 @@ static struct dw_hdmi_plat_data imx6dl_hdmi_drv_data = { .encoder_prepare= dw_hdmi_imx_encoder_prepare, .mpll_cfg = imx_mpll_cfg, .cur_ctr= imx_cur_ctr, + .sym_term = imx_sym_term, .dev_type = IMX6DL_HDMI, }; diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 6683b63..1688ec9 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -37,6 +37,12 @@ s
[PATCH v10 07/11] dt-bindings: add document for dw_hdmi
Signed-off-by: Andy Yan --- Changes in v10: None Changes in v9: None Changes in v8: - correct some spelling mistake - modify ddc-i2c-bus and interrupt description Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None .../devicetree/bindings/drm/bridge/dw_hdmi.txt | 40 ++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt new file mode 100644 index 000..0558442 --- /dev/null +++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt @@ -0,0 +1,40 @@ +DesignWare HDMI bridge bindings + +Required properities: +- compatible: platform specific such as: + * "fsl,imx6q-hdmi" + * "fsl,imx6dl-hdmi" + * "rockchip,rk3288-dw-hdmi" +- reg: physical base address of the controller and length +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing +- interrupts: The HDMI interrupt number + +Optional properties +- reg-io-width: the width of the reg:1,4, default set to 1 if not present + +Example: + hdmi: hdmi@012 { + compatible = "fsl,imx6q-hdmi"; + reg = <0x0012 0x9000>; + interrupts = <0 115 0x04>; + gpr = <&gpr>; + clocks = <&clks 123>, <&clks 124>; + clock-names = "iahb", "isfr"; + ddc-i2c-bus = <&i2c2>; + + port@0 { + reg = <0>; + + hdmi_mux_0: endpoint { + remote-endpoint = <&ipu1_di0_hdmi>; + }; + }; + + port@1 { + reg = <1>; + + hdmi_mux_1: endpoint { + remote-endpoint = <&ipu1_di1_hdmi>; + }; + }; + }; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v10 06/11] drm: bridge/dw_hdmi: clear i2cmphy_stat0 reg in hdmi_phy_wait_i2c_done
HDMI_IH_I2CMPHY_STAT0 is a clear on write register, which indicates i2cm operation status(i2c transfer done or error), every hdmi phy register configuration must check this register to make sure the configuration has complete. But the indication bit should be cleared after check, otherwise the corresponding bit will hold on forever, this may give a wrong signal for next check. Signed-off-by: Andy Yan --- Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index 05e7156..4f9a5c0 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -640,11 +640,15 @@ static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi, static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) { - while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { + u32 val; + + while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { if (msec-- == 0) return false; udelay(1000); } + hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0); + return true; } -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v10 08/11] drm: bridge/dw_hdmi: add support for multi byte register width access
On rockchip rk3288, only word(32-bit) accesses are permitted for hdmi registers. Byte width accesses (writeb, readb) generate an imprecise external abort. Signed-off-by: Andy Yan --- Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: - move some modification to patch#6 - refactor register access without reg_shift Changes in v5: - refactor reg-io-width Changes in v4: None Changes in v3: - split multi register access to one indepent patch Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c | 57 +++- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index 4f9a5c0..d7bf46d 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -101,6 +101,11 @@ struct hdmi_data_info { struct hdmi_vmode video_mode; }; +union dw_reg_ptr { + u32 __iomem *p32; + u8 __iomem *p8; +}; + struct dw_hdmi { struct drm_connector connector; struct drm_encoder encoder; @@ -121,20 +126,43 @@ struct dw_hdmi { struct regmap *regmap; struct i2c_adapter *ddc; - void __iomem *regs; + union dw_reg_ptr regs; unsigned int sample_rate; int ratio; + + void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); + u8 (*read)(struct dw_hdmi *hdmi, int offset); }; +static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset) +{ + writel(val, hdmi->regs.p32 + offset); +} + +static u8 dw_hdmi_readl(struct dw_hdmi *hdmi, int offset) +{ + return readl(hdmi->regs.p32 + offset); +} + +static void dw_hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) +{ + writeb(val, hdmi->regs.p8 + offset); +} + +static u8 dw_hdmi_readb(struct dw_hdmi *hdmi, int offset) +{ + return readb(hdmi->regs.p8 + offset); +} + static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) { - writeb(val, hdmi->regs + offset); + hdmi->write(hdmi, val, offset); } static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) { - return readb(hdmi->regs + offset); + return hdmi->read(hdmi, offset); } static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) @@ -1528,6 +1556,23 @@ static int dw_hdmi_bind(struct device *dev, struct device *master, void *data) struct device_node *ddc_node; struct resource *iores; int ret, irq; + u32 val = 1; + + of_property_read_u32(np, "reg-io-width", &val); + + switch (val) { + case 4: + hdmi->write = dw_hdmi_writel; + hdmi->read = dw_hdmi_readl; + break; + case 1: + hdmi->write = dw_hdmi_writeb; + hdmi->read = dw_hdmi_readb; + break; + default: + dev_err(dev, "reg-io-width must be 1 or 4\n"); + return -EINVAL; + } ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); if (ddc_node) { @@ -1554,9 +1599,9 @@ static int dw_hdmi_bind(struct device *dev, struct device *master, void *data) return ret; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->regs = devm_ioremap_resource(dev, iores); - if (IS_ERR(hdmi->regs)) - return PTR_ERR(hdmi->regs); + hdmi->regs.p32 = devm_ioremap_resource(dev, iores); + if (IS_ERR(hdmi->regs.p32)) + return PTR_ERR(hdmi->regs.p32); if (hdmi->plat_data->setup) hdmi->priv = hdmi->plat_data->setup(pdev); -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v10 09/11] drm: bridge/dw_hdmi: convert dw-hdmi to drm_bridge mode
From: Yakir Yang keep the connector & birdge in dw_hdmi.c, handle encoder in dw_hdmi-imx.c, as most of the encoder operation are platform specific such as crtc select and panel format set Signed-off-by: Andy Yan Signed-off-by: Yakir Yang --- Changes in v10: None Changes in v9: None Changes in v8: None Changes in v7: None Changes in v6: - move some modification from patch#5 Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c | 228 +++--- drivers/staging/imx-drm/dw_hdmi-imx.c | 143 ++--- include/drm/bridge/dw_hdmi.h | 13 +- 3 files changed, 198 insertions(+), 186 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index d7bf46d..a2876fe 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -11,7 +11,6 @@ * Copyright (C) 2010, Guennadi Liakhovetski */ -#include #include #include #include @@ -108,7 +107,8 @@ union dw_reg_ptr { struct dw_hdmi { struct drm_connector connector; - struct drm_encoder encoder; + struct drm_encoder *encoder; + struct drm_bridge *bridge; enum dw_hdmi_devtype dev_type; struct device *dev; @@ -1331,6 +1331,50 @@ static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) dw_hdmi_phy_disable(hdmi); } +static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + dw_hdmi_setup(hdmi, mode); + + /* Store the display mode for plugin/DKMS poweron events */ + memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); +} + +static bool dw_hdmi_bridge_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void dw_hdmi_bridge_disable(struct drm_bridge *bridge) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + dw_hdmi_poweroff(hdmi); +} + +static void dw_hdmi_bridge_enable(struct drm_bridge *bridge) +{ + struct dw_hdmi *hdmi = bridge->driver_private; + + dw_hdmi_poweron(hdmi); +} + +static void dw_hdmi_bridge_destroy(struct drm_bridge *bridge) +{ + drm_bridge_cleanup(bridge); + kfree(bridge); +} + +static void dw_hdmi_bridge_nope(struct drm_bridge *bridge) +{ + /* do nothing */ +} + static enum drm_connector_status dw_hdmi_connector_detect(struct drm_connector *connector, bool force) { @@ -1386,60 +1430,7 @@ static struct drm_encoder *dw_hdmi_connector_best_encoder(struct drm_connector struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi, connector); - return &hdmi->encoder; -} - -static void dw_hdmi_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - struct dw_hdmi *hdmi = container_of(encoder, struct dw_hdmi, encoder); - - dw_hdmi_setup(hdmi, mode); - - /* Store the display mode for plugin/DKMS poweron events */ - memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); -} - -static bool dw_hdmi_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static void dw_hdmi_encoder_disable(struct drm_encoder *encoder) -{ -} - -static void dw_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode) -{ - struct dw_hdmi *hdmi = container_of(encoder, struct dw_hdmi, encoder); - - if (mode) - dw_hdmi_poweroff(hdmi); - else - dw_hdmi_poweron(hdmi); -} - -static void dw_hdmi_encoder_prepare(struct drm_encoder *encoder) -{ - struct dw_hdmi *hdmi = container_of(encoder, struct dw_hdmi, encoder); - - dw_hdmi_poweroff(hdmi); - - if (hdmi->plat_data->encoder_prepare) - hdmi->plat_data->encoder_prepare(&hdmi->connector, encoder); -} - -static void dw_hdmi_encoder_commit(struct drm_encoder *encoder) -{ - struct dw_hdmi *hdmi = container_of(encoder, struct dw_hdmi, encoder); - - if (hdmi->plat_data->encoder_commit) - hdmi->plat_data->encoder_commit(hdmi->priv, encoder); - - dw_hdmi_poweron(hdmi); + return hdmi->encoder; } void dw_hdmi_connector_destroy(struct drm_connector *connector) @@ -1448,19 +1439,6 @@ void dw_hdmi_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } -static struct drm_encoder_funcs dw_hdmi_encoder_fun
[PATCH v10 10/11] dt-bindings: Add documentation for rockchip dw hdmi
Signed-off-by: Andy Yan --- Changes in v10: None Changes in v9: None Changes in v8: - Add documentation for rockchip dw hdmi Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None .../devicetree/bindings/video/dw_hdmi-rockchip.txt | 43 ++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt diff --git a/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt new file mode 100644 index 000..6ea6764 --- /dev/null +++ b/Documentation/devicetree/bindings/video/dw_hdmi-rockchip.txt @@ -0,0 +1,43 @@ +Rockchip specific extensions to the Synopsys Designware HDMI + + +Required properties: +- compatible: "rockchip,rk3288-dw-hdmi"; +- reg: physical base address of the controller and length +- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing +- clocks: from common clock binding: handle to hdmi clock. +- clock-names: should be "clk" "hdcp_clk" +- rockchip,grf: this soc should set GRF regs to mux vopl/vopb. +- interrupts: HDMI interrupt number +- ports: contain a port node with endpoint definitions as defined in + Documentation/devicetree/bindings/media/video-interfaces.txt. For + vopb,set the reg = <0> and set the reg = <1> for vopl. +- reg-io-width: the width of the reg:1,4, the value should be 4 on + rk3288 platform + +Example: +hdmi: hdmi@ff98 { + compatible = "rockchip,rk3288-dw-hdmi"; + reg = <0xff98 0x2>; + reg-io-width = <4>; + ddc-i2c-bus = <&i2c5>; + rockchip,grf = <&grf>; + interrupts = ; + clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>; + clock-names = "clk", "hdcp_clk"; + status = "disabled"; + ports { + hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + hdmi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_hdmi>; + }; + hdmi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_hdmi>; + }; + }; + }; +}; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v10 11/11] drm: bridge/dw_hdmi: add rockchip rk3288 support
Rockchip RK3288 hdmi is compatible with dw_hdmi Signed-off-by: Andy Yan --- Changes in v10: - add more display mode support mpll configuration for rk3288 Changes in v9: - move some phy configuration to platform driver Changes in v8: None Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/dw_hdmi.c| 10 + drivers/gpu/drm/bridge/dw_hdmi.h| 3 +- drivers/gpu/drm/rockchip/Kconfig| 10 + drivers/gpu/drm/rockchip/Makefile | 2 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 355 include/drm/bridge/dw_hdmi.h| 1 + 6 files changed, 379 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index a2876fe..1dd1f0b 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -715,6 +715,13 @@ static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) HDMI_PHY_CONF0_ENTMDS_MASK); } +static void dw_hdmi_phy_enable_spare(struct dw_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, +HDMI_PHY_CONF0_SPARECTRL_OFFSET, +HDMI_PHY_CONF0_SPARECTRL_MASK); +} + static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) { hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, @@ -846,6 +853,9 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi, unsigned char prep, dw_hdmi_phy_gen2_txpwron(hdmi, 1); dw_hdmi_phy_gen2_pddq(hdmi, 0); + if (hdmi->dev_type == RK3288_HDMI) + dw_hdmi_phy_enable_spare(hdmi, 1); + /*Wait for PHY PLL lock */ msec = 5; do { diff --git a/drivers/gpu/drm/bridge/dw_hdmi.h b/drivers/gpu/drm/bridge/dw_hdmi.h index b8412a9..30a6b28 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.h +++ b/drivers/gpu/drm/bridge/dw_hdmi.h @@ -837,7 +837,8 @@ enum { HDMI_PHY_CONF0_PDZ_OFFSET = 7, HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, - HDMI_PHY_CONF0_SPARECTRL = 0x20, + HDMI_PHY_CONF0_SPARECTRL_MASK = 0x20, + HDMI_PHY_CONF0_SPARECTRL_OFFSET = 5, HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index 0ff6682..06371ae 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -15,3 +15,13 @@ config DRM_ROCKCHIP management to userspace. This driver does not provide 2D or 3D acceleration; acceleration is performed by other IP found on the SoC. + +config ROCKCHIP_DW_HDMI +bool "Rockchip specific extensions for Synopsys DW HDMI" +depends on DRM_ROCKCHIP +select DRM_DW_HDMI +help + This selects support for Rockchip SoC specific extensions + for the Synopsys DesignWare HDMI driver. If you want to + enable HDMI on RK3288 based SoC, you should selet this + option. diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile index b3a5193..347e65c 100644 --- a/drivers/gpu/drm/rockchip/Makefile +++ b/drivers/gpu/drm/rockchip/Makefile @@ -4,5 +4,5 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \ rockchip_drm_gem.o rockchip_drm_vop.o - +rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c new file mode 100644 index 000..16cad75 --- /dev/null +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rockchip_drm_drv.h" +#include "rockchip_drm_vop.h" + +#define GRF_SOC_CON60x025c +#define HDMI_SEL_VOP_LIT(1 << 4) + +struct rockchip_hdmi { + struct device *dev; + struct clk *clk; + struct clk *hdcp_clk; + struct regmap *regmap; + struct drm_encoder encoder; +}; + +#define to_rockchip_hdmi(x)container_of(x, struct rockchip_hdmi, x) + +static const struct mpll_config rockchip_mpll_cfg[] = { + { + 2700, { + { 0x00b3, 0x}, + { 0x2153,