1c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K/* 2c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * hdmi.c 3c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * 4c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * HDMI interface DSS driver setting for TI's OMAP4 family of processor. 5c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ 6c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * Authors: Yong Zhi 7c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * Mythri pk <mythripk@ti.com> 8c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * 9c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * This program is free software; you can redistribute it and/or modify it 10c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * under the terms of the GNU General Public License version 2 as published by 11c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * the Free Software Foundation. 12c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * 13c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * This program is distributed in the hope that it will be useful, but WITHOUT 14c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * more details. 17c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * 18c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * You should have received a copy of the GNU General Public License along with 19c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * this program. If not, see <http://www.gnu.org/licenses/>. 20c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K */ 21c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 22c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#define DSS_SUBSYS_NAME "HDMI" 23c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 24c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include <linux/kernel.h> 25c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include <linux/module.h> 26c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include <linux/err.h> 27c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include <linux/io.h> 28c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include <linux/interrupt.h> 29c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include <linux/mutex.h> 30c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include <linux/delay.h> 31c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include <linux/string.h> 3224e6289c029b0cf5b4f75e12c1b66000d441c9edTomi Valkeinen#include <linux/platform_device.h> 334fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen#include <linux/pm_runtime.h> 344fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen#include <linux/clk.h> 35a0b38cc4d35e095f14ab0f486135f8a619ebfc14Tomi Valkeinen#include <video/omapdss.h> 36ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 37ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 38ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#include <sound/soc.h> 39ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#include <sound/pcm_params.h> 407334167bf18e708e275164a3c44bb3f0c193d0c4Mythri P K#include "ti_hdmi_4xxx_ip.h" 41ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#endif 42c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 4394c52987d293ec2aeb75993a3e33b7c36159668cMythri P K#include "ti_hdmi.h" 44c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K#include "dss.h" 45ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#include "dss_features.h" 46c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 4795a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K#define HDMI_WP 0x0 4895a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K#define HDMI_CORE_SYS 0x400 4995a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K#define HDMI_CORE_AV 0x900 5095a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K#define HDMI_PLLCTRL 0x200 5195a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K#define HDMI_PHY 0x300 5295a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K 537c1f1ecac9240663db357ae0f30761a7ee7c8463Mythri P K/* HDMI EDID Length move this */ 547c1f1ecac9240663db357ae0f30761a7ee7c8463Mythri P K#define HDMI_EDID_MAX_LENGTH 256 557c1f1ecac9240663db357ae0f30761a7ee7c8463Mythri P K#define EDID_TIMING_DESCRIPTOR_SIZE 0x12 567c1f1ecac9240663db357ae0f30761a7ee7c8463Mythri P K#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36 577c1f1ecac9240663db357ae0f30761a7ee7c8463Mythri P K#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80 587c1f1ecac9240663db357ae0f30761a7ee7c8463Mythri P K#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 597c1f1ecac9240663db357ae0f30761a7ee7c8463Mythri P K#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 607c1f1ecac9240663db357ae0f30761a7ee7c8463Mythri P K 61b44e45825dbe30f32c770b98c38555b6bd331760Tomi Valkeinen#define HDMI_DEFAULT_REGN 16 628d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen#define HDMI_DEFAULT_REGM2 1 638d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen 64c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kstatic struct { 65c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct mutex lock; 66c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct omap_display_platform_data *pdata; 67c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct platform_device *pdev; 6895a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K struct hdmi_ip_data ip_data; 694fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 704fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen struct clk *sys_clk; 71c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} hdmi; 72c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 73c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K/* 74c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * Logic for the below structure : 75c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * user enters the CEA or VESA timings by specifying the HDMI/DVI code. 76c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * There is a correspondence between CEA/VESA timing and code, please 77c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * refer to section 6.3 in HDMI 1.3 specification for timing code. 78c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * 79c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * In the below structure, cea_vesa_timings corresponds to all OMAP4 80c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * supported CEA and VESA timing values.code_cea corresponds to the CEA 81c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * code, It is used to get the timing from cea_vesa_timing array.Similarly 82c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * with code_vesa. Code_index is used for back mapping, that is once EDID 83c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * is read from the TV, EDID is parsed to find the timing values and then 84c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * map it to corresponding CEA or VESA index. 85c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K */ 86c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 8746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P Kstatic const struct hdmi_config cea_timings[] = { 88a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, 89a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, 90a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, 91a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} }, 92a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} }, 93a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} }, 94a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} }, 95a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} }, 96a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} }, 97a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} }, 98a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} }, 99a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} }, 100a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, 101a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, 102a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, 10346095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K}; 10446095b2d96bac92c2cc5ca557ec7de73e13311abMythri P Kstatic const struct hdmi_config vesa_timings[] = { 105a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K/* VESA From Here */ 106a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, 107a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, 108a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} }, 109a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} }, 110a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} }, 111a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} }, 112a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} }, 113a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} }, 114a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} }, 115a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} }, 116a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} }, 117a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} }, 118a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} }, 119a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} }, 120a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} }, 121a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} }, 122a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} }, 123a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} }, 124a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } 125c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K}; 126c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 1274fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic int hdmi_runtime_get(void) 1284fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen{ 1294fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen int r; 1304fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 1314fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen DSSDBG("hdmi_runtime_get\n"); 1324fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 133a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja /* 134a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja * HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled. 135a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja * This should be removed later. 136a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja */ 137a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja r = dss_runtime_get(); 138a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja if (r < 0) 139a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja goto err_get_dss; 140a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja 1414fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen r = pm_runtime_get_sync(&hdmi.pdev->dev); 1424fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen WARN_ON(r < 0); 143a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja if (r < 0) 144a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja goto err_get_hdmi; 145a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja 146a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja return 0; 147a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja 148a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Tanejaerr_get_hdmi: 149a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja dss_runtime_put(); 150a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Tanejaerr_get_dss: 151a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja return r; 1524fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen} 1534fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 1544fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic void hdmi_runtime_put(void) 1554fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen{ 1564fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen int r; 1574fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 1584fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen DSSDBG("hdmi_runtime_put\n"); 1594fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 1600eaf9f52e94f756147dbfe1faf1f77a02378dbf9Tomi Valkeinen r = pm_runtime_put_sync(&hdmi.pdev->dev); 1614fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen WARN_ON(r < 0); 162a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja 163a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja /* 164a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja * HACK: This is added to complement the dss_runtime_get() call in 165a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja * hdmi_runtime_get(). This should be removed later. 166a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja */ 167a247ce78ca3fa041f3e6b1187c4ae96c7016e83aArchit Taneja dss_runtime_put(); 1684fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen} 1694fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 170c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kint hdmi_init_display(struct omap_dss_device *dssdev) 171c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 172c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("init_display\n"); 173c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 17460634a28bc5467ade316574c4aa728c5bff7947eMythri P K dss_init_hdmi_ip_ops(&hdmi.ip_data); 175c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return 0; 176c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 177c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 17846095b2d96bac92c2cc5ca557ec7de73e13311abMythri P Kstatic const struct hdmi_config *hdmi_find_timing( 17946095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K const struct hdmi_config *timings_arr, 18046095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K int len) 181c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 18246095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K int i; 183c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 18446095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K for (i = 0; i < len; i++) { 1859e4ed603e6ec71da9e0a7484a694f98dff869068Mythri P K if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code) 18646095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K return &timings_arr[i]; 18746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K } 18846095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K return NULL; 18946095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K} 190c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 19146095b2d96bac92c2cc5ca557ec7de73e13311abMythri P Kstatic const struct hdmi_config *hdmi_get_timings(void) 19246095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K{ 19346095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K const struct hdmi_config *arr; 19446095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K int len; 19546095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K 1969e4ed603e6ec71da9e0a7484a694f98dff869068Mythri P K if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) { 19746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K arr = vesa_timings; 19846095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K len = ARRAY_SIZE(vesa_timings); 19946095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K } else { 20046095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K arr = cea_timings; 20146095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K len = ARRAY_SIZE(cea_timings); 20246095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K } 20346095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K 20446095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K return hdmi_find_timing(arr, len); 20546095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K} 20646095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K 20746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P Kstatic bool hdmi_timings_compare(struct omap_video_timings *timing1, 20846095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K const struct hdmi_video_timings *timing2) 20946095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K{ 21046095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; 21146095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K 21246095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K if ((timing2->pixel_clock == timing1->pixel_clock) && 21346095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K (timing2->x_res == timing1->x_res) && 21446095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K (timing2->y_res == timing1->y_res)) { 215c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 21646095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; 21746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; 21846095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; 21946095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp; 22046095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K 22146095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ 22246095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K "timing2_hsync = %d timing2_vsync = %d\n", 22346095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K timing1_hsync, timing1_vsync, 22446095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K timing2_hsync, timing2_vsync); 22546095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K 22646095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K if ((timing1_hsync == timing2_hsync) && 22746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K (timing1_vsync == timing2_vsync)) { 22846095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K return true; 22946095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K } 230c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 23146095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K return false; 232c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 233c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 234c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kstatic struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) 235c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 23646095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K int i; 237c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct hdmi_cm cm = {-1}; 238c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("hdmi_get_code\n"); 239c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 24046095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { 24146095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { 24246095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K cm = cea_timings[i].cm; 24346095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K goto end; 24446095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K } 24546095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K } 24646095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { 24746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { 24846095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K cm = vesa_timings[i].cm; 24946095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K goto end; 250c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 251c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 252c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 25346095b2d96bac92c2cc5ca557ec7de73e13311abMythri P Kend: return cm; 254c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 255c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 256c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 257c3dc6a7afb47735b82a4c0061e814454a649dbfcArchit Tanejaunsigned long hdmi_get_pixel_clock(void) 258c3dc6a7afb47735b82a4c0061e814454a649dbfcArchit Taneja{ 259c3dc6a7afb47735b82a4c0061e814454a649dbfcArchit Taneja /* HDMI Pixel Clock in Mhz */ 260a05ce78f308fa22b6254995c25ff79e82a27de75Mythri P K return hdmi.ip_data.cfg.timings.pixel_clock * 1000; 261c3dc6a7afb47735b82a4c0061e814454a649dbfcArchit Taneja} 262c3dc6a7afb47735b82a4c0061e814454a649dbfcArchit Taneja 2636cb07b256af233965663d6dfc329d7df3dcae786Archit Tanejastatic void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, 2646cb07b256af233965663d6dfc329d7df3dcae786Archit Taneja struct hdmi_pll_info *pi) 265c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 2666cb07b256af233965663d6dfc329d7df3dcae786Archit Taneja unsigned long clkin, refclk; 267c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K u32 mf; 268c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 2694fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen clkin = clk_get_rate(hdmi.sys_clk) / 10000; 270c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K /* 271c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * Input clock is predivided by N + 1 272c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * out put of which is reference clk 273c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K */ 2748d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen if (dssdev->clocks.hdmi.regn == 0) 2758d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen pi->regn = HDMI_DEFAULT_REGN; 2768d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen else 2778d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen pi->regn = dssdev->clocks.hdmi.regn; 2788d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen 279b44e45825dbe30f32c770b98c38555b6bd331760Tomi Valkeinen refclk = clkin / pi->regn; 280c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 2818d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen if (dssdev->clocks.hdmi.regm2 == 0) 2828d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen pi->regm2 = HDMI_DEFAULT_REGM2; 2838d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen else 2848d88767a4377171752c22ac39bcb2b505eb751daTomi Valkeinen pi->regm2 = dssdev->clocks.hdmi.regm2; 285c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 286c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K /* 287dd2116a35aa9a5a7b71e1d21f30aec8927434d19Mythri P K * multiplier is pixel_clk/ref_clk 288dd2116a35aa9a5a7b71e1d21f30aec8927434d19Mythri P K * Multiplying by 100 to avoid fractional part removal 289dd2116a35aa9a5a7b71e1d21f30aec8927434d19Mythri P K */ 290dd2116a35aa9a5a7b71e1d21f30aec8927434d19Mythri P K pi->regm = phy * pi->regm2 / refclk; 291dd2116a35aa9a5a7b71e1d21f30aec8927434d19Mythri P K 292dd2116a35aa9a5a7b71e1d21f30aec8927434d19Mythri P K /* 293c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * fractional multiplier is remainder of the difference between 294c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * multiplier and actual phy(required pixel clock thus should be 295c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * multiplied by 2^18(262144) divided by the reference clock 296c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K */ 297dd2116a35aa9a5a7b71e1d21f30aec8927434d19Mythri P K mf = (phy - pi->regm / pi->regm2 * refclk) * 262144; 298dd2116a35aa9a5a7b71e1d21f30aec8927434d19Mythri P K pi->regmf = pi->regm2 * mf / refclk; 299c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 300c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K /* 301c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * Dcofreq should be set to 1 if required pixel clock 302c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * is greater than 1000MHz 303c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K */ 304c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K pi->dcofreq = phy > 1000 * 100; 305b44e45825dbe30f32c770b98c38555b6bd331760Tomi Valkeinen pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10; 306c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 3077b27da548389cede637653033211369a2c9678f7Mythri P K /* Set the reference clock to sysclk reference */ 3087b27da548389cede637653033211369a2c9678f7Mythri P K pi->refsel = HDMI_REFSEL_SYSCLK; 3097b27da548389cede637653033211369a2c9678f7Mythri P K 310c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); 311c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); 312c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 313c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 314c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kstatic int hdmi_power_on(struct omap_dss_device *dssdev) 315c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 31646095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K int r; 31746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K const struct hdmi_config *timing; 318c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct omap_video_timings *p; 3196cb07b256af233965663d6dfc329d7df3dcae786Archit Taneja unsigned long phy; 320c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 3214fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen r = hdmi_runtime_get(); 3224fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen if (r) 3234fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen return r; 324c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 3257797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen dss_mgr_disable(dssdev->manager); 326c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 327c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K p = &dssdev->panel.timings; 328c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 329c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", 330c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K dssdev->panel.timings.x_res, 331c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K dssdev->panel.timings.y_res); 332c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 33346095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K timing = hdmi_get_timings(); 33446095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K if (timing == NULL) { 33546095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K /* HDMI code 4 corresponds to 640 * 480 VGA */ 3369e4ed603e6ec71da9e0a7484a694f98dff869068Mythri P K hdmi.ip_data.cfg.cm.code = 4; 33746095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K /* DVI mode 1 corresponds to HDMI 0 to DVI */ 3389e4ed603e6ec71da9e0a7484a694f98dff869068Mythri P K hdmi.ip_data.cfg.cm.mode = HDMI_DVI; 33946095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K hdmi.ip_data.cfg = vesa_timings[0]; 34046095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K } else { 34146095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K hdmi.ip_data.cfg = *timing; 34246095b2d96bac92c2cc5ca557ec7de73e13311abMythri P K } 343c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K phy = p->pixel_clock; 344c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 3457b27da548389cede637653033211369a2c9678f7Mythri P K hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); 346c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 34760634a28bc5467ade316574c4aa728c5bff7947eMythri P K hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); 348c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 34995a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 35060634a28bc5467ade316574c4aa728c5bff7947eMythri P K r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); 351c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (r) { 352c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("Failed to lock PLL\n"); 353c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K goto err; 354c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 355c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 35660634a28bc5467ade316574c4aa728c5bff7947eMythri P K r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); 357c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (r) { 358c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("Failed to start PHY\n"); 359c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K goto err; 360c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 361c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 36260634a28bc5467ade316574c4aa728c5bff7947eMythri P K hdmi.ip_data.ops->video_configure(&hdmi.ip_data); 363c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 364c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K /* Make selection of HDMI in DSS */ 365c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 366c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 367c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K /* Select the dispc clock source as PRCM clock, to ensure that it is not 368c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * DSI PLL source as the clock selected by DSI PLL might not be 369c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * sufficient for the resolution selected / that can be changed 370c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * dynamically by user. This can be moved to single location , say 371c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K * Boardfile. 372c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K */ 3736cb07b256af233965663d6dfc329d7df3dcae786Archit Taneja dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); 374c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 375c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K /* bypass TV gamma table */ 376c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K dispc_enable_gamma_table(0); 377c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 378c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K /* tv size */ 379c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K dispc_set_digit_size(dssdev->panel.timings.x_res, 380c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K dssdev->panel.timings.y_res); 381c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 38260634a28bc5467ade316574c4aa728c5bff7947eMythri P K hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1); 383c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 38433ca237f80555cde41c17682991a2b58d2f14da5Tomi Valkeinen r = dss_mgr_enable(dssdev->manager); 38533ca237f80555cde41c17682991a2b58d2f14da5Tomi Valkeinen if (r) 38633ca237f80555cde41c17682991a2b58d2f14da5Tomi Valkeinen goto err_mgr_enable; 3873870c909f2fc880dece633772f2551aa70d26979Tomi Valkeinen 388c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return 0; 38933ca237f80555cde41c17682991a2b58d2f14da5Tomi Valkeinen 39033ca237f80555cde41c17682991a2b58d2f14da5Tomi Valkeinenerr_mgr_enable: 39133ca237f80555cde41c17682991a2b58d2f14da5Tomi Valkeinen hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); 39233ca237f80555cde41c17682991a2b58d2f14da5Tomi Valkeinen hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 39333ca237f80555cde41c17682991a2b58d2f14da5Tomi Valkeinen hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 394c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kerr: 3954fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen hdmi_runtime_put(); 396c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return -EIO; 397c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 398c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 399c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kstatic void hdmi_power_off(struct omap_dss_device *dssdev) 400c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 4017797c6da64852b06b585b7eca8d3f657bfc9fa47Tomi Valkeinen dss_mgr_disable(dssdev->manager); 402c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 40360634a28bc5467ade316574c4aa728c5bff7947eMythri P K hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0); 40460634a28bc5467ade316574c4aa728c5bff7947eMythri P K hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 40560634a28bc5467ade316574c4aa728c5bff7947eMythri P K hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); 4064fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen hdmi_runtime_put(); 407c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 408c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 409c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kint omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, 410c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct omap_video_timings *timings) 411c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 412c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct hdmi_cm cm; 413c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 414c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K cm = hdmi_get_code(timings); 415c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (cm.code == -1) { 416c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return -EINVAL; 417c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 418c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 419c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return 0; 420c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 421c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 422c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 423c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kvoid omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev) 424c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 425c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct hdmi_cm cm; 426c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 427c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K cm = hdmi_get_code(&dssdev->panel.timings); 4289e4ed603e6ec71da9e0a7484a694f98dff869068Mythri P K hdmi.ip_data.cfg.cm.code = cm.code; 4299e4ed603e6ec71da9e0a7484a694f98dff869068Mythri P K hdmi.ip_data.cfg.cm.mode = cm.mode; 430fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen 431fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { 432fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen int r; 433fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen 434fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen hdmi_power_off(dssdev); 435fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen 436fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen r = hdmi_power_on(dssdev); 437fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen if (r) 438fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen DSSERR("failed to power on device\n"); 439fa70dc5f472ddc261ad429f2c12eb7ac31c90b87Tomi Valkeinen } 440c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 441c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 442162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P Kvoid hdmi_dump_regs(struct seq_file *s) 443162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K{ 444162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K mutex_lock(&hdmi.lock); 445162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K 446162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K if (hdmi_runtime_get()) 447162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K return; 448162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K 449162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); 450162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); 451162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s); 452162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s); 453162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K 454162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K hdmi_runtime_put(); 455162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K mutex_unlock(&hdmi.lock); 456162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K} 457162874d5f5fa8aac7ff406825f152abb22d3c6c2Mythri P K 458470245652d98274568ac81a875c8312e73a433efTomi Valkeinenint omapdss_hdmi_read_edid(u8 *buf, int len) 459470245652d98274568ac81a875c8312e73a433efTomi Valkeinen{ 460470245652d98274568ac81a875c8312e73a433efTomi Valkeinen int r; 461470245652d98274568ac81a875c8312e73a433efTomi Valkeinen 462470245652d98274568ac81a875c8312e73a433efTomi Valkeinen mutex_lock(&hdmi.lock); 463470245652d98274568ac81a875c8312e73a433efTomi Valkeinen 464470245652d98274568ac81a875c8312e73a433efTomi Valkeinen r = hdmi_runtime_get(); 465470245652d98274568ac81a875c8312e73a433efTomi Valkeinen BUG_ON(r); 466470245652d98274568ac81a875c8312e73a433efTomi Valkeinen 467470245652d98274568ac81a875c8312e73a433efTomi Valkeinen r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len); 468470245652d98274568ac81a875c8312e73a433efTomi Valkeinen 469470245652d98274568ac81a875c8312e73a433efTomi Valkeinen hdmi_runtime_put(); 470470245652d98274568ac81a875c8312e73a433efTomi Valkeinen mutex_unlock(&hdmi.lock); 471470245652d98274568ac81a875c8312e73a433efTomi Valkeinen 472470245652d98274568ac81a875c8312e73a433efTomi Valkeinen return r; 473470245652d98274568ac81a875c8312e73a433efTomi Valkeinen} 474470245652d98274568ac81a875c8312e73a433efTomi Valkeinen 475759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinenbool omapdss_hdmi_detect(void) 476759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen{ 477759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen int r; 478759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen 479759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen mutex_lock(&hdmi.lock); 480759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen 481759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen r = hdmi_runtime_get(); 482759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen BUG_ON(r); 483759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen 484759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen r = hdmi.ip_data.ops->detect(&hdmi.ip_data); 485759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen 486759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen hdmi_runtime_put(); 487759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen mutex_unlock(&hdmi.lock); 488759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen 489759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen return r == 1; 490759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen} 491759593ffa7e05ebea9b21135cad179982331f5d8Tomi Valkeinen 492c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kint omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) 493c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 494c49d005b6cc8491fad5b24f82805be2d6bcbd3ddTomi Valkeinen struct omap_dss_hdmi_data *priv = dssdev->data; 495c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K int r = 0; 496c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 497c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("ENTER hdmi_display_enable\n"); 498c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 499c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K mutex_lock(&hdmi.lock); 500c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 50105e1d6060743e34e3a9db65346168dc688f9223eTomi Valkeinen if (dssdev->manager == NULL) { 50205e1d6060743e34e3a9db65346168dc688f9223eTomi Valkeinen DSSERR("failed to enable display: no manager\n"); 50305e1d6060743e34e3a9db65346168dc688f9223eTomi Valkeinen r = -ENODEV; 50405e1d6060743e34e3a9db65346168dc688f9223eTomi Valkeinen goto err0; 50505e1d6060743e34e3a9db65346168dc688f9223eTomi Valkeinen } 50605e1d6060743e34e3a9db65346168dc688f9223eTomi Valkeinen 507c49d005b6cc8491fad5b24f82805be2d6bcbd3ddTomi Valkeinen hdmi.ip_data.hpd_gpio = priv->hpd_gpio; 508c49d005b6cc8491fad5b24f82805be2d6bcbd3ddTomi Valkeinen 509c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K r = omap_dss_start_device(dssdev); 510c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (r) { 511c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSERR("failed to start device\n"); 512c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K goto err0; 513c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 514c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 515c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (dssdev->platform_enable) { 516c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K r = dssdev->platform_enable(dssdev); 517c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (r) { 518c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSERR("failed to enable GPIO's\n"); 519c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K goto err1; 520c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 521c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 522c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 523c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K r = hdmi_power_on(dssdev); 524c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (r) { 525c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSERR("failed to power on device\n"); 526c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K goto err2; 527c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 528c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 529c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K mutex_unlock(&hdmi.lock); 530c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return 0; 531c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 532c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kerr2: 533c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (dssdev->platform_disable) 534c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K dssdev->platform_disable(dssdev); 535c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kerr1: 536c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K omap_dss_stop_device(dssdev); 537c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kerr0: 538c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K mutex_unlock(&hdmi.lock); 539c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return r; 540c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 541c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 542c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kvoid omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) 543c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 544c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSDBG("Enter hdmi_display_disable\n"); 545c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 546c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K mutex_lock(&hdmi.lock); 547c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 548c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K hdmi_power_off(dssdev); 549c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 550c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (dssdev->platform_disable) 551c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K dssdev->platform_disable(dssdev); 552c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 553c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K omap_dss_stop_device(dssdev); 554c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 555c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K mutex_unlock(&hdmi.lock); 556c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 557c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 55882335c4cc2edf57afece9399441a7480c2a1b055Ricardo Neri#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 55982335c4cc2edf57afece9399441a7480c2a1b055Ricardo Neri defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 560ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 561edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neristatic int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd, 562edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri struct snd_soc_dai *dai) 563edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri{ 564edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri struct snd_soc_pcm_runtime *rtd = substream->private_data; 565edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri struct snd_soc_codec *codec = rtd->codec; 566edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri struct platform_device *pdev = to_platform_device(codec->dev); 567edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec); 568edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri int err = 0; 569edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri 570edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri if (!(ip_data->ops) && !(ip_data->ops->audio_enable)) { 571edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri dev_err(&pdev->dev, "Cannot enable/disable audio\n"); 572edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri return -ENODEV; 573edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri } 574edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri 575edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri switch (cmd) { 576edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri case SNDRV_PCM_TRIGGER_START: 577edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri case SNDRV_PCM_TRIGGER_RESUME: 578edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 579edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri ip_data->ops->audio_enable(ip_data, true); 580edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri break; 581edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri case SNDRV_PCM_TRIGGER_STOP: 582edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri case SNDRV_PCM_TRIGGER_SUSPEND: 583edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 584edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri ip_data->ops->audio_enable(ip_data, false); 585edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri break; 586edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri default: 587edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri err = -EINVAL; 588edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri } 589edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri return err; 590edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri} 591edefcdad6a57657a236638c937ccd5a3af272d02Ricardo Neri 592284cb318c8f84744f073d4f4d3820946afaf5442Ricardo Neristatic int hdmi_audio_hw_params(struct snd_pcm_substream *substream, 593ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri struct snd_pcm_hw_params *params, 594ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri struct snd_soc_dai *dai) 595ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri{ 596284cb318c8f84744f073d4f4d3820946afaf5442Ricardo Neri struct snd_soc_pcm_runtime *rtd = substream->private_data; 597284cb318c8f84744f073d4f4d3820946afaf5442Ricardo Neri struct snd_soc_codec *codec = rtd->codec; 598284cb318c8f84744f073d4f4d3820946afaf5442Ricardo Neri struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec); 599ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri struct hdmi_audio_format audio_format; 600ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri struct hdmi_audio_dma audio_dma; 601ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri struct hdmi_core_audio_config core_cfg; 602ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri struct hdmi_core_infoframe_audio aud_if_cfg; 603ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri int err, n, cts; 604ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri enum hdmi_core_audio_sample_freq sample_freq; 605ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 606ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri switch (params_format(params)) { 607ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri case SNDRV_PCM_FORMAT_S16_LE: 608ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.word_max_length = 609ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri HDMI_AUDIO_I2S_MAX_WORD_20BITS; 610ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_16_BITS; 611ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.in_length_bits = 612ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri HDMI_AUDIO_I2S_INPUT_LENGTH_16; 613ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; 614ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; 615ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; 616ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; 617ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_dma.transfer_size = 0x10; 618ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri break; 619ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri case SNDRV_PCM_FORMAT_S24_LE: 620ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.word_max_length = 621ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri HDMI_AUDIO_I2S_MAX_WORD_24BITS; 622ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.word_length = HDMI_AUDIO_I2S_CHST_WORD_24_BITS; 623ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.in_length_bits = 624ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri HDMI_AUDIO_I2S_INPUT_LENGTH_24; 625ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_ONESAMPLE; 626ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.sample_size = HDMI_AUDIO_SAMPLE_24BITS; 627ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.justification = HDMI_AUDIO_JUSTIFY_RIGHT; 628ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; 629ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_dma.transfer_size = 0x20; 630ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri break; 631ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri default: 632ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri return -EINVAL; 633ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri } 634ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 635ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri switch (params_rate(params)) { 636ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri case 32000: 637ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri sample_freq = HDMI_AUDIO_FS_32000; 638ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri break; 639ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri case 44100: 640ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri sample_freq = HDMI_AUDIO_FS_44100; 641ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri break; 642ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri case 48000: 643ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri sample_freq = HDMI_AUDIO_FS_48000; 644ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri break; 645ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri default: 646ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri return -EINVAL; 647ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri } 648ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 64995a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K err = hdmi_config_audio_acr(ip_data, params_rate(params), &n, &cts); 650ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri if (err < 0) 651ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri return err; 652ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 653ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Audio wrapper config */ 654ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; 655ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.active_chnnls_msk = 0x03; 656ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.type = HDMI_AUDIO_TYPE_LPCM; 657ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST; 658ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Disable start/stop signals of IEC 60958 blocks */ 659ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF; 660ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 661ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_dma.block_size = 0xC0; 662ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; 663ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri audio_dma.fifo_threshold = 0x20; /* in number of samples */ 664ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 66595a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi_wp_audio_config_dma(ip_data, &audio_dma); 66695a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi_wp_audio_config_format(ip_data, &audio_format); 667ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 668ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* 669ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri * I2S config 670ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri */ 671ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.en_high_bitrate_aud = false; 672ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Only used with high bitrate audio */ 673ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.cbit_order = false; 674ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Serial data and word select should change on sck rising edge */ 675ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; 676ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; 677ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Set I2S word select polarity */ 678ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.ws_polarity = HDMI_AUDIO_I2S_WS_POLARITY_LOW_IS_LEFT; 679ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; 680ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Set serial data to word select shift. See Phillips spec. */ 681ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; 682ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Enable one of the four available serial data channels */ 683ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; 684ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 685ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Core audio config */ 686ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.freq_sample = sample_freq; 687ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.n = n; 688ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.cts = cts; 689ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { 690ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.aud_par_busclk = 0; 691ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_SW; 692f15511e23db4e1deb6bf6a3c88c04ba85434e142Ricardo Neri core_cfg.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK); 693ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri } else { 694ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.aud_par_busclk = (((128 * 31) - 1) << 8); 695ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.cts_mode = HDMI_AUDIO_CTS_MODE_HW; 696ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.use_mclk = true; 697ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri } 698f15511e23db4e1deb6bf6a3c88c04ba85434e142Ricardo Neri 699f15511e23db4e1deb6bf6a3c88c04ba85434e142Ricardo Neri if (core_cfg.use_mclk) 700f15511e23db4e1deb6bf6a3c88c04ba85434e142Ricardo Neri core_cfg.mclk_mode = HDMI_AUDIO_MCLK_128FS; 701ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; 702ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.en_spdif = false; 703ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Use sample frequency from channel status word */ 704ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.fs_override = true; 705ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Enable ACR packets */ 706ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.en_acr_pkt = true; 707ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Disable direct streaming digital audio */ 708ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.en_dsd_audio = false; 709ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Use parallel audio interface */ 710ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri core_cfg.en_parallel_aud_input = true; 711ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 71295a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi_core_audio_config(ip_data, &core_cfg); 713ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 714ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* 715ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri * Configure packet 716ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri * info frame audio see doc CEA861-D page 74 717ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri */ 718ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri aud_if_cfg.db1_coding_type = HDMI_INFOFRAME_AUDIO_DB1CT_FROM_STREAM; 719ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri aud_if_cfg.db1_channel_count = 2; 720ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri aud_if_cfg.db2_sample_freq = HDMI_INFOFRAME_AUDIO_DB2SF_FROM_STREAM; 721ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri aud_if_cfg.db2_sample_size = HDMI_INFOFRAME_AUDIO_DB2SS_FROM_STREAM; 722ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri aud_if_cfg.db4_channel_alloc = 0x00; 723ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri aud_if_cfg.db5_downmix_inh = false; 724ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri aud_if_cfg.db5_lsv = 0; 725ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 72695a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi_core_audio_infoframe_config(ip_data, &aud_if_cfg); 727ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri return 0; 728ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri} 729ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 730ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neristatic int hdmi_audio_startup(struct snd_pcm_substream *substream, 731ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri struct snd_soc_dai *dai) 732ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri{ 7339e4ed603e6ec71da9e0a7484a694f98dff869068Mythri P K if (!hdmi.ip_data.cfg.cm.mode) { 734ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri pr_err("Current video settings do not support audio.\n"); 735ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri return -EIO; 736ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri } 737ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri return 0; 738ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri} 739ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 740b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neristatic int hdmi_audio_codec_probe(struct snd_soc_codec *codec) 741b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neri{ 742b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neri struct hdmi_ip_data *priv = &hdmi.ip_data; 743b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neri 744b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neri snd_soc_codec_set_drvdata(codec, priv); 745b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neri return 0; 746b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neri} 747b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neri 748ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neristatic struct snd_soc_codec_driver hdmi_audio_codec_drv = { 749b17ce117322a446f13716132e47b672d7bf25a30Ricardo Neri .probe = hdmi_audio_codec_probe, 750ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri}; 751ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 752ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neristatic struct snd_soc_dai_ops hdmi_audio_codec_ops = { 753ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .hw_params = hdmi_audio_hw_params, 754ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .trigger = hdmi_audio_trigger, 755ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .startup = hdmi_audio_startup, 756ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri}; 757ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 758ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neristatic struct snd_soc_dai_driver hdmi_codec_dai_drv = { 759ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .name = "hdmi-audio-codec", 760ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .playback = { 761ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .channels_min = 2, 762ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .channels_max = 2, 763ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .rates = SNDRV_PCM_RATE_32000 | 764ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, 765ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .formats = SNDRV_PCM_FMTBIT_S16_LE | 766ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri SNDRV_PCM_FMTBIT_S24_LE, 767ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri }, 768ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri .ops = &hdmi_audio_codec_ops, 769ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri}; 77082335c4cc2edf57afece9399441a7480c2a1b055Ricardo Neri#endif 77182335c4cc2edf57afece9399441a7480c2a1b055Ricardo Neri 7724fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic int hdmi_get_clocks(struct platform_device *pdev) 7734fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen{ 7744fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen struct clk *clk; 7754fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 7764fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen clk = clk_get(&pdev->dev, "sys_clk"); 7774fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen if (IS_ERR(clk)) { 7784fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen DSSERR("can't get sys_clk\n"); 7794fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen return PTR_ERR(clk); 7804fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen } 7814fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 7824fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen hdmi.sys_clk = clk; 7834fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 7844fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen return 0; 7854fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen} 7864fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 7874fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic void hdmi_put_clocks(void) 7884fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen{ 7894fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen if (hdmi.sys_clk) 7904fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen clk_put(hdmi.sys_clk); 7914fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen} 7924fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 793c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K/* HDMI HW IP initialisation */ 794c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kstatic int omapdss_hdmihw_probe(struct platform_device *pdev) 795c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 796c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K struct resource *hdmi_mem; 7974fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen int r; 798c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 799c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K hdmi.pdata = pdev->dev.platform_data; 800c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K hdmi.pdev = pdev; 801c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 802c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K mutex_init(&hdmi.lock); 803c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 804c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); 805c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K if (!hdmi_mem) { 806c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSERR("can't get IORESOURCE_MEM HDMI\n"); 807c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return -EINVAL; 808c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 809c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 810c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K /* Base address taken from platform */ 81195a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi.ip_data.base_wp = ioremap(hdmi_mem->start, 81295a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K resource_size(hdmi_mem)); 81395a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K if (!hdmi.ip_data.base_wp) { 814c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K DSSERR("can't ioremap WP\n"); 815c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return -ENOMEM; 816c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K } 817c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 8184fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen r = hdmi_get_clocks(pdev); 8194fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen if (r) { 82095a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K iounmap(hdmi.ip_data.base_wp); 8214fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen return r; 8224fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen } 8234fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8244fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen pm_runtime_enable(&pdev->dev); 8254fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 82695a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS; 82795a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi.ip_data.core_av_offset = HDMI_CORE_AV; 82895a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 82995a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K hdmi.ip_data.phy_offset = HDMI_PHY; 83095a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K 831c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K hdmi_panel_init(); 832c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 833ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 834ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 835ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 836ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri /* Register ASoC codec DAI */ 8374fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen r = snd_soc_register_codec(&pdev->dev, &hdmi_audio_codec_drv, 838ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri &hdmi_codec_dai_drv, 1); 8394fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen if (r) { 840ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri DSSERR("can't register ASoC HDMI audio codec\n"); 8414fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen return r; 842ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri } 843ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#endif 844c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return 0; 845c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 846c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 847c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kstatic int omapdss_hdmihw_remove(struct platform_device *pdev) 848c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 849c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K hdmi_panel_exit(); 850c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 851ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \ 852ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE) 853ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri snd_soc_unregister_codec(&pdev->dev); 854ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri#endif 855ad44cc3298872c4d4f4b034df9163c3944ae8c1cRicardo Neri 8564fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen pm_runtime_disable(&pdev->dev); 8574fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8584fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen hdmi_put_clocks(); 8594fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 86095a8aeb6c56ec80fb847e44328e3b53b9934dcbfMythri P K iounmap(hdmi.ip_data.base_wp); 861c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 862c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return 0; 863c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 864c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 8654fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic int hdmi_runtime_suspend(struct device *dev) 8664fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen{ 8674fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen clk_disable(hdmi.sys_clk); 8684fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8694fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen dispc_runtime_put(); 8704fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen dss_runtime_put(); 8714fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8724fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen return 0; 8734fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen} 8744fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8754fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic int hdmi_runtime_resume(struct device *dev) 8764fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen{ 8774fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen int r; 8784fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8794fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen r = dss_runtime_get(); 8804fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen if (r < 0) 8814fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen goto err_get_dss; 8824fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8834fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen r = dispc_runtime_get(); 8844fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen if (r < 0) 8854fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen goto err_get_dispc; 8864fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8874fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8884fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen clk_enable(hdmi.sys_clk); 8894fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8904fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen return 0; 8914fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8924fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenerr_get_dispc: 8934fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen dss_runtime_put(); 8944fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenerr_get_dss: 8954fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen return r; 8964fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen} 8974fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 8984fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinenstatic const struct dev_pm_ops hdmi_pm_ops = { 8994fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen .runtime_suspend = hdmi_runtime_suspend, 9004fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen .runtime_resume = hdmi_runtime_resume, 9014fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen}; 9024fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen 903c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kstatic struct platform_driver omapdss_hdmihw_driver = { 904c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K .probe = omapdss_hdmihw_probe, 905c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K .remove = omapdss_hdmihw_remove, 906c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K .driver = { 907c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K .name = "omapdss_hdmi", 908c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K .owner = THIS_MODULE, 9094fbafaf371be780ed2cd73a520dfeafa1ea73e24Tomi Valkeinen .pm = &hdmi_pm_ops, 910c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K }, 911c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K}; 912c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 913c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kint hdmi_init_platform_driver(void) 914c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 915c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return platform_driver_register(&omapdss_hdmihw_driver); 916c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 917c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K 918c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P Kvoid hdmi_uninit_platform_driver(void) 919c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K{ 920c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K return platform_driver_unregister(&omapdss_hdmihw_driver); 921c3198a5e83121d6e3d01816f15164f158f4301d8Mythri P K} 922