linux/drivers/gpu/drm/xilinx/xilinx_cresample.c
<<
>>
Prefs
   1/*
   2 * Xilinx Chroma Resampler 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_cresample.h"
  28
  29/* registers */
  30/* general control registers */
  31#define CRESAMPLE_CONTROL               0x0000
  32
  33/* horizontal and vertical active frame size */
  34#define CRESAMPLE_ACTIVE_SIZE           0x0020
  35
  36/* control register bit definition */
  37#define CRESAMPLE_CTL_EN                (1 << 0)        /* enable */
  38#define CRESAMPLE_CTL_RU                (1 << 1)        /* reg update */
  39#define CRESAMPLE_CTL_RESET             (1 << 31)       /* instant reset */
  40
  41struct xilinx_cresample {
  42        void __iomem *base;
  43        const char *input_format_name;
  44        const char *output_format_name;
  45};
  46
  47/* enable cresample */
  48void xilinx_cresample_enable(struct xilinx_cresample *cresample)
  49{
  50        u32 reg;
  51
  52        reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
  53        xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
  54                          reg | CRESAMPLE_CTL_EN);
  55}
  56
  57/* disable cresample */
  58void xilinx_cresample_disable(struct xilinx_cresample *cresample)
  59{
  60        u32 reg;
  61
  62        reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
  63        xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
  64                          reg & ~CRESAMPLE_CTL_EN);
  65}
  66
  67/* configure cresample */
  68void xilinx_cresample_configure(struct xilinx_cresample *cresample,
  69                                int hactive, int vactive)
  70{
  71        /* configure hsize and vsize */
  72        xilinx_drm_writel(cresample->base, CRESAMPLE_ACTIVE_SIZE,
  73                          (vactive << 16) | hactive);
  74}
  75
  76/* reset cresample */
  77void xilinx_cresample_reset(struct xilinx_cresample *cresample)
  78{
  79        u32 reg;
  80
  81        xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
  82                          CRESAMPLE_CTL_RESET);
  83
  84        /* enable register update */
  85        reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
  86        xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
  87                          reg | CRESAMPLE_CTL_RU);
  88}
  89
  90/* get an input format */
  91const char *
  92xilinx_cresample_get_input_format_name(struct xilinx_cresample *cresample)
  93{
  94        return cresample->input_format_name;
  95}
  96
  97/* get an output format */
  98const char *
  99xilinx_cresample_get_output_format_name(struct xilinx_cresample *cresample)
 100{
 101        return cresample->output_format_name;
 102}
 103
 104static const struct of_device_id xilinx_cresample_of_match[] = {
 105        { .compatible = "xlnx,v-cresample-3.01.a" },
 106        { /* end of table */ },
 107};
 108
 109struct xilinx_cresample *xilinx_cresample_probe(struct device *dev,
 110                                                struct device_node *node)
 111{
 112        struct xilinx_cresample *cresample;
 113        const struct of_device_id *match;
 114        struct resource res;
 115        int ret;
 116
 117        match = of_match_node(xilinx_cresample_of_match, node);
 118        if (!match) {
 119                dev_err(dev, "failed to match the device node\n");
 120                return ERR_PTR(-ENODEV);
 121        }
 122
 123        cresample = devm_kzalloc(dev, sizeof(*cresample), GFP_KERNEL);
 124        if (!cresample)
 125                return ERR_PTR(-ENOMEM);
 126
 127        ret = of_address_to_resource(node, 0, &res);
 128        if (ret) {
 129                dev_err(dev, "failed to of_address_to_resource\n");
 130                return ERR_PTR(ret);
 131        }
 132
 133        cresample->base = devm_ioremap_resource(dev, &res);
 134        if (IS_ERR(cresample->base))
 135                return ERR_CAST(cresample->base);
 136
 137        ret = of_property_read_string(node, "xlnx,input-format",
 138                                      &cresample->input_format_name);
 139        if (ret) {
 140                dev_warn(dev, "failed to get an input format prop\n");
 141                return ERR_PTR(ret);
 142        }
 143
 144        ret = of_property_read_string(node, "xlnx,output-format",
 145                                      &cresample->output_format_name);
 146        if (ret) {
 147                dev_warn(dev, "failed to get an output format prop\n");
 148                return ERR_PTR(ret);
 149        }
 150
 151        xilinx_cresample_reset(cresample);
 152
 153        return cresample;
 154}
 155