1/* 2 * ppi.c Analog Devices Parallel Peripheral Interface driver 3 * 4 * Copyright (c) 2011 Analog Devices Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20#include <linux/module.h> 21#include <linux/slab.h> 22#include <linux/platform_device.h> 23 24#include <asm/bfin_ppi.h> 25#include <asm/blackfin.h> 26#include <asm/cacheflush.h> 27#include <asm/dma.h> 28#include <asm/portmux.h> 29 30#include <media/blackfin/ppi.h> 31 32static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler); 33static void ppi_detach_irq(struct ppi_if *ppi); 34static int ppi_start(struct ppi_if *ppi); 35static int ppi_stop(struct ppi_if *ppi); 36static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params); 37static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr); 38 39static const struct ppi_ops ppi_ops = { 40 .attach_irq = ppi_attach_irq, 41 .detach_irq = ppi_detach_irq, 42 .start = ppi_start, 43 .stop = ppi_stop, 44 .set_params = ppi_set_params, 45 .update_addr = ppi_update_addr, 46}; 47 48static irqreturn_t ppi_irq_err(int irq, void *dev_id) 49{ 50 struct ppi_if *ppi = dev_id; 51 const struct ppi_info *info = ppi->info; 52 53 switch (info->type) { 54 case PPI_TYPE_PPI: 55 { 56 struct bfin_ppi_regs *reg = info->base; 57 unsigned short status; 58 59 /* register on bf561 is cleared when read 60 * others are W1C 61 */ 62 status = bfin_read16(®->status); 63 if (status & 0x3000) 64 ppi->err = true; 65 bfin_write16(®->status, 0xff00); 66 break; 67 } 68 case PPI_TYPE_EPPI: 69 { 70 struct bfin_eppi_regs *reg = info->base; 71 unsigned short status; 72 73 status = bfin_read16(®->status); 74 if (status & 0x2) 75 ppi->err = true; 76 bfin_write16(®->status, 0xffff); 77 break; 78 } 79 case PPI_TYPE_EPPI3: 80 { 81 struct bfin_eppi3_regs *reg = info->base; 82 unsigned long stat; 83 84 stat = bfin_read32(®->stat); 85 if (stat & 0x2) 86 ppi->err = true; 87 bfin_write32(®->stat, 0xc0ff); 88 break; 89 } 90 default: 91 break; 92 } 93 94 return IRQ_HANDLED; 95} 96 97static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler) 98{ 99 const struct ppi_info *info = ppi->info; 100 int ret; 101 102 ret = request_dma(info->dma_ch, "PPI_DMA"); 103 104 if (ret) { 105 pr_err("Unable to allocate DMA channel for PPI\n"); 106 return ret; 107 } 108 set_dma_callback(info->dma_ch, handler, ppi); 109 110 if (ppi->err_int) { 111 ret = request_irq(info->irq_err, ppi_irq_err, 0, "PPI ERROR", ppi); 112 if (ret) { 113 pr_err("Unable to allocate IRQ for PPI\n"); 114 free_dma(info->dma_ch); 115 } 116 } 117 return ret; 118} 119 120static void ppi_detach_irq(struct ppi_if *ppi) 121{ 122 const struct ppi_info *info = ppi->info; 123 124 if (ppi->err_int) 125 free_irq(info->irq_err, ppi); 126 free_dma(info->dma_ch); 127} 128 129static int ppi_start(struct ppi_if *ppi) 130{ 131 const struct ppi_info *info = ppi->info; 132 133 /* enable DMA */ 134 enable_dma(info->dma_ch); 135 136 /* enable PPI */ 137 ppi->ppi_control |= PORT_EN; 138 switch (info->type) { 139 case PPI_TYPE_PPI: 140 { 141 struct bfin_ppi_regs *reg = info->base; 142 bfin_write16(®->control, ppi->ppi_control); 143 break; 144 } 145 case PPI_TYPE_EPPI: 146 { 147 struct bfin_eppi_regs *reg = info->base; 148 bfin_write32(®->control, ppi->ppi_control); 149 break; 150 } 151 case PPI_TYPE_EPPI3: 152 { 153 struct bfin_eppi3_regs *reg = info->base; 154 bfin_write32(®->ctl, ppi->ppi_control); 155 break; 156 } 157 default: 158 return -EINVAL; 159 } 160 161 SSYNC(); 162 return 0; 163} 164 165static int ppi_stop(struct ppi_if *ppi) 166{ 167 const struct ppi_info *info = ppi->info; 168 169 /* disable PPI */ 170 ppi->ppi_control &= ~PORT_EN; 171 switch (info->type) { 172 case PPI_TYPE_PPI: 173 { 174 struct bfin_ppi_regs *reg = info->base; 175 bfin_write16(®->control, ppi->ppi_control); 176 break; 177 } 178 case PPI_TYPE_EPPI: 179 { 180 struct bfin_eppi_regs *reg = info->base; 181 bfin_write32(®->control, ppi->ppi_control); 182 break; 183 } 184 case PPI_TYPE_EPPI3: 185 { 186 struct bfin_eppi3_regs *reg = info->base; 187 bfin_write32(®->ctl, ppi->ppi_control); 188 break; 189 } 190 default: 191 return -EINVAL; 192 } 193 194 /* disable DMA */ 195 clear_dma_irqstat(info->dma_ch); 196 disable_dma(info->dma_ch); 197 198 SSYNC(); 199 return 0; 200} 201 202static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params) 203{ 204 const struct ppi_info *info = ppi->info; 205 int dma32 = 0; 206 int dma_config, bytes_per_line; 207 int hcount, hdelay, samples_per_line; 208 209#ifdef CONFIG_PINCTRL 210 static const char * const pin_state[] = {"8bit", "16bit", "24bit"}; 211 struct pinctrl *pctrl; 212 struct pinctrl_state *pstate; 213 214 if (params->dlen > 24 || params->dlen <= 0) 215 return -EINVAL; 216 pctrl = devm_pinctrl_get(ppi->dev); 217 pstate = pinctrl_lookup_state(pctrl, 218 pin_state[(params->dlen + 7) / 8 - 1]); 219 if (pinctrl_select_state(pctrl, pstate)) 220 return -EINVAL; 221#endif 222 223 bytes_per_line = params->width * params->bpp / 8; 224 /* convert parameters unit from pixels to samples */ 225 hcount = params->width * params->bpp / params->dlen; 226 hdelay = params->hdelay * params->bpp / params->dlen; 227 samples_per_line = params->line * params->bpp / params->dlen; 228 if (params->int_mask == 0xFFFFFFFF) 229 ppi->err_int = false; 230 else 231 ppi->err_int = true; 232 233 dma_config = (DMA_FLOW_STOP | RESTART | DMA2D | DI_EN_Y); 234 ppi->ppi_control = params->ppi_control & ~PORT_EN; 235 if (!(ppi->ppi_control & PORT_DIR)) 236 dma_config |= WNR; 237 switch (info->type) { 238 case PPI_TYPE_PPI: 239 { 240 struct bfin_ppi_regs *reg = info->base; 241 242 if (params->ppi_control & DMA32) 243 dma32 = 1; 244 245 bfin_write16(®->control, ppi->ppi_control); 246 bfin_write16(®->count, samples_per_line - 1); 247 bfin_write16(®->frame, params->frame); 248 break; 249 } 250 case PPI_TYPE_EPPI: 251 { 252 struct bfin_eppi_regs *reg = info->base; 253 254 if ((params->ppi_control & PACK_EN) 255 || (params->ppi_control & 0x38000) > DLEN_16) 256 dma32 = 1; 257 258 bfin_write32(®->control, ppi->ppi_control); 259 bfin_write16(®->line, samples_per_line); 260 bfin_write16(®->frame, params->frame); 261 bfin_write16(®->hdelay, hdelay); 262 bfin_write16(®->vdelay, params->vdelay); 263 bfin_write16(®->hcount, hcount); 264 bfin_write16(®->vcount, params->height); 265 break; 266 } 267 case PPI_TYPE_EPPI3: 268 { 269 struct bfin_eppi3_regs *reg = info->base; 270 271 if ((params->ppi_control & PACK_EN) 272 || (params->ppi_control & 0x70000) > DLEN_16) 273 dma32 = 1; 274 275 bfin_write32(®->ctl, ppi->ppi_control); 276 bfin_write32(®->line, samples_per_line); 277 bfin_write32(®->frame, params->frame); 278 bfin_write32(®->hdly, hdelay); 279 bfin_write32(®->vdly, params->vdelay); 280 bfin_write32(®->hcnt, hcount); 281 bfin_write32(®->vcnt, params->height); 282 if (params->int_mask) 283 bfin_write32(®->imsk, params->int_mask & 0xFF); 284 if (ppi->ppi_control & PORT_DIR) { 285 u32 hsync_width, vsync_width, vsync_period; 286 287 hsync_width = params->hsync 288 * params->bpp / params->dlen; 289 vsync_width = params->vsync * samples_per_line; 290 vsync_period = samples_per_line * params->frame; 291 bfin_write32(®->fs1_wlhb, hsync_width); 292 bfin_write32(®->fs1_paspl, samples_per_line); 293 bfin_write32(®->fs2_wlvb, vsync_width); 294 bfin_write32(®->fs2_palpf, vsync_period); 295 } 296 break; 297 } 298 default: 299 return -EINVAL; 300 } 301 302 if (dma32) { 303 dma_config |= WDSIZE_32 | PSIZE_32; 304 set_dma_x_count(info->dma_ch, bytes_per_line >> 2); 305 set_dma_x_modify(info->dma_ch, 4); 306 set_dma_y_modify(info->dma_ch, 4); 307 } else { 308 dma_config |= WDSIZE_16 | PSIZE_16; 309 set_dma_x_count(info->dma_ch, bytes_per_line >> 1); 310 set_dma_x_modify(info->dma_ch, 2); 311 set_dma_y_modify(info->dma_ch, 2); 312 } 313 set_dma_y_count(info->dma_ch, params->height); 314 set_dma_config(info->dma_ch, dma_config); 315 316 SSYNC(); 317 return 0; 318} 319 320static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr) 321{ 322 set_dma_start_addr(ppi->info->dma_ch, addr); 323} 324 325struct ppi_if *ppi_create_instance(struct platform_device *pdev, 326 const struct ppi_info *info) 327{ 328 struct ppi_if *ppi; 329 330 if (!info || !info->pin_req) 331 return NULL; 332 333#ifndef CONFIG_PINCTRL 334 if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) { 335 dev_err(&pdev->dev, "request peripheral failed\n"); 336 return NULL; 337 } 338#endif 339 340 ppi = kzalloc(sizeof(*ppi), GFP_KERNEL); 341 if (!ppi) { 342 peripheral_free_list(info->pin_req); 343 dev_err(&pdev->dev, "unable to allocate memory for ppi handle\n"); 344 return NULL; 345 } 346 ppi->ops = &ppi_ops; 347 ppi->info = info; 348 ppi->dev = &pdev->dev; 349 350 pr_info("ppi probe success\n"); 351 return ppi; 352} 353EXPORT_SYMBOL(ppi_create_instance); 354 355void ppi_delete_instance(struct ppi_if *ppi) 356{ 357 peripheral_free_list(ppi->info->pin_req); 358 kfree(ppi); 359} 360EXPORT_SYMBOL(ppi_delete_instance); 361 362MODULE_DESCRIPTION("Analog Devices PPI driver"); 363MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>"); 364MODULE_LICENSE("GPL v2"); 365