linux/drivers/gpu/drm/xilinx/xilinx_rgb2yuv.c
<<
>>
Prefs
   1/*
   2 * Xilinx rgb to yuv converter support for Xilinx DRM KMS
   3 *
   4 *  Copyright (C) 2013 Xilinx, Inc.
   5 *
   6 *  Author: Hyun Woo Kwon <hyunk@xilinx.com>
   7 *
   8 * This software is licensed under the terms of the GNU General Public
   9 * License version 2, as published by the Free Software Foundation, and
  10 * may be copied, distributed, and modified under those terms.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17
  18#include <linux/device.h>
  19#include <linux/err.h>
  20#include <linux/io.h>
  21#include <linux/of.h>
  22#include <linux/of_address.h>
  23#include <linux/slab.h>
  24
  25#include "xilinx_drm_drv.h"
  26
  27#include "xilinx_rgb2yuv.h"
  28
  29/* registers */
  30/* control register */
  31#define RGB_CONTROL     0x000
  32/* active size v,h */
  33#define RGB_ACTIVE_SIZE 0x020
  34
  35/* control register bit definition */
  36#define RGB_CTL_EN      (1 << 0)        /* enable */
  37#define RGB_CTL_RUE     (1 << 1)        /* register update enable */
  38#define RGB_RST_RESET   (1 << 31)       /* instant reset */
  39
  40struct xilinx_rgb2yuv {
  41        void __iomem *base;
  42};
  43
  44/* enable rgb2yuv */
  45void xilinx_rgb2yuv_enable(struct xilinx_rgb2yuv *rgb2yuv)
  46{
  47        u32 reg;
  48
  49        reg = xilinx_drm_readl(rgb2yuv->base, RGB_CONTROL);
  50        xilinx_drm_writel(rgb2yuv->base, RGB_CONTROL, reg | RGB_CTL_EN);
  51}
  52
  53/* disable rgb2yuv */
  54void xilinx_rgb2yuv_disable(struct xilinx_rgb2yuv *rgb2yuv)
  55{
  56        u32 reg;
  57
  58        reg = xilinx_drm_readl(rgb2yuv->base, RGB_CONTROL);
  59        xilinx_drm_writel(rgb2yuv->base, RGB_CONTROL, reg & ~RGB_CTL_EN);
  60}
  61
  62/* configure rgb2yuv */
  63void xilinx_rgb2yuv_configure(struct xilinx_rgb2yuv *rgb2yuv,
  64                              int hactive, int vactive)
  65{
  66        xilinx_drm_writel(rgb2yuv->base, RGB_ACTIVE_SIZE,
  67                          (vactive << 16) | hactive);
  68}
  69
  70/* reset rgb2yuv */
  71void xilinx_rgb2yuv_reset(struct xilinx_rgb2yuv *rgb2yuv)
  72{
  73        u32 reg;
  74
  75        xilinx_drm_writel(rgb2yuv->base, RGB_CONTROL, RGB_RST_RESET);
  76
  77        /* enable register update */
  78        reg = xilinx_drm_readl(rgb2yuv->base, RGB_CONTROL);
  79        xilinx_drm_writel(rgb2yuv->base, RGB_CONTROL, reg | RGB_CTL_RUE);
  80}
  81
  82static const struct of_device_id xilinx_rgb2yuv_of_match[] = {
  83        { .compatible = "xlnx,v-rgb2ycrcb-6.01.a" },
  84        { /* end of table */ },
  85};
  86
  87/* probe rgb2yuv */
  88struct xilinx_rgb2yuv *xilinx_rgb2yuv_probe(struct device *dev,
  89                                            struct device_node *node)
  90{
  91        struct xilinx_rgb2yuv *rgb2yuv;
  92        const struct of_device_id *match;
  93        struct resource res;
  94        int ret;
  95
  96        match = of_match_node(xilinx_rgb2yuv_of_match, node);
  97        if (!match) {
  98                dev_err(dev, "failed to match the device node\n");
  99                return ERR_PTR(-ENODEV);
 100        }
 101
 102        rgb2yuv = devm_kzalloc(dev, sizeof(*rgb2yuv), GFP_KERNEL);
 103        if (!rgb2yuv)
 104                return ERR_PTR(-ENOMEM);
 105
 106        ret = of_address_to_resource(node, 0, &res);
 107        if (ret) {
 108                dev_err(dev, "failed to of_address_to_resource\n");
 109                return ERR_PTR(ret);
 110        }
 111
 112        rgb2yuv->base = devm_ioremap_resource(dev, &res);
 113        if (IS_ERR(rgb2yuv->base))
 114                return ERR_CAST(rgb2yuv->base);
 115
 116        xilinx_rgb2yuv_reset(rgb2yuv);
 117
 118        return rgb2yuv;
 119}
 120